C++ 类 & 对象
在 C++ 中,**类(class)**是用于封装数据与操作(成员变量和成员函数)的用户自定义类型;**对象(object)**则是该类型的具体实例。下面按要点分章说明其定义、使用及高级特性。
1. 定义与访问控制
class Person {
public: // 公有访问:外部可见
Person(const std::string& n, int a);
void sayHello() const;
private: // 私有访问:仅类内部可见
std::string name;
int age;
protected: // 受保护访问:在派生类中可见
void log() const;
};
public
、private
、protected
决定成员可访问性。struct
与class
区别仅在默认访问权限:struct
默认public
,class
默认private
。
2. 构造函数 & 析构函数
Person::Person(const std::string& n, int a)
: name(n), age(a) // 成员初始化列表
{}
Person::~Person() { // 析构函数,资源释放
// 如需手动释放资源(一般用智能指针或容器管理)
}
- 构造函数(Constructor)用于初始化对象,可重载多个参数版本。
- 析构函数(Destructor,
~ClassName
)在对象生命周期结束时调用,用于释放资源。 - C++11 支持
default
与delete
:Person() = default; // 使用编译器生成的构造 Person(const Person&) = delete; // 禁用拷贝构造
3. 成员函数与常成员
void Person::sayHello() const { // const 成员函数,不修改成员
std::cout << "Hello, I'm " << name
<< ", " << age << " years old.\n";
}
- 常成员函数(
…() const
)保证不修改对象状态,可被常对象调用。 - 内联成员函数(在类内定义)自动含
inline
属性。
4. 数据封装与访问器
class Rectangle {
double width, height;
public:
double area() const { return width * height; }
void setSize(double w, double h) {
width = w; height = h;
}
};
- 将成员设为私有,通过公有的 getter/setter(访问器/修改器)控制读写并可加入校验逻辑。
5. 静态成员与常量成员
class Counter {
public:
static int count; // 静态成员(类级别,共享)
static int getCount() { return count; }
};
int Counter::count = 0; // 必须在类外定义
class Config {
public:
static constexpr double PI = 3.1415926535; // 编译期常量
};
static
成员属于类本身,不依赖对象。constexpr
可用于常量初始化,编译期可求值。
6. 拷贝与移动语义
class Buffer {
char* data;
size_t size;
public:
Buffer(size_t n): size(n) {
data = new char[n];
}
~Buffer() { delete[] data; }
// 拷贝构造(深拷贝)
Buffer(const Buffer& other)
: size(other.size) {
data = new char[size];
std::memcpy(data, other.data, size);
}
// 移动构造(窃取资源)
Buffer(Buffer&& other) noexcept
: data(other.data), size(other.size) {
other.data = nullptr;
other.size = 0;
}
// 同理可定义拷贝/移动赋值运算符
};
- Rule of Five:若定义自定义析构、拷贝/移动构造或赋值,最好都显式定义,以管理资源。
7. 继承与多态
class Shape {
public:
virtual double area() const = 0; // 纯虚函数——抽象基类
virtual ~Shape() = default;
};
class Circle : public Shape {
double r;
public:
Circle(double radius): r(radius) {}
double area() const override {
return 3.14159 * r * r;
}
};
- 基类定义 虚函数(
virtual
),派生类用override
标注重写。 - 抽象类(含纯虚函数
=0
)不可实例化。 - 多态:通过基类指针/引用调用
area()
时,会动态绑定到派生类实现。
8. 对象的创建与存储
// 栈上
Person p{"Alice", 30};
// 堆上
auto* pp = new Person{"Bob", 25};
delete pp;
// 智能指针管理
auto sp = std::make_shared<Person>("Carol", 28);
- 对象可在栈、堆或静态区创建,推荐使用智能指针(
unique_ptr
、shared_ptr
)管理动态对象。
9. 友元(Friend)
class A {
int secret;
friend void reveal(const A&); // declare friend
};
void reveal(const A& a) {
std::cout << a.secret; // 访问私有成员
}
- 友元函数/类可访问类的私有和受保护成员,用于重载输出运算符等场景。
10. 模板与泛型
template<typename T>
class Box {
T value;
public:
Box(const T& v): value(v) {}
T get() const { return value; }
};
- 类模板支持泛型编程,可像
Box<int>
、Box<std::string>
一样实例化多种类型。
小结
- 类是封装数据和操作的蓝图,对象是其实例。
- 掌握构造/析构、拷贝/移动语义可有效管理资源。
- 使用访问控制、虚函数、多态与模板,可设计灵活、安全且高效的 C++ 程序。