1124 字
3 分钟
【CPP】类
整理自 0319、0320、0323、0324 相关章节,已校对并补充。
类与对象
- 类:类型的蓝图,描述属性(成员变量)与行为(成员函数)。
- 对象:类的实例。
访问控制
| 关键字 | 类内 | 派生类 | 类外 |
|---|---|---|---|
public | ✓ | ✓ | ✓ |
protected | ✓ | ✓ | ✗ |
private | ✓ | ✗ | ✗ |
- 默认成员访问权限为
private(struct默认为public)。 - 访问说明符作用到下一个说明符或类结束。
class Demo { int num; // privatepublic: void setNum(int v);};
void Demo::setNum(int v) { this->num = v; // 成员函数内可用 this}类外定义成员函数
class Stock {public: void set_tot();};
// 类内声明、类外定义;若在类外定义且希望内联,可加 inlineinline void Stock::set_tot() { /* ... */ }在类内定义的函数隐式为 inline(是否真内联由编译器决定)。
构造函数
- 与类名相同,无返回值(不写
void)。 - 创建对象时自动调用,可重载。
- 未自定义任何构造函数时,编译器生成默认构造函数(无参或带默认参数)。
- 自定义了任意构造函数后,编译器不再自动生成默认构造函数;需要时应显式写
= default或自己写无参构造。
class Foo {public: Foo() = default; Foo(int x) : x_(x) {}private: int x_;};初始化列表
构造函数后加 : 成员(初值), ...,按成员在类中声明顺序初始化(与列表书写顺序无关)。
必须使用初始化列表的情况:
const成员- 引用成员
- 没有默认构造函数的子对象成员
- 基类需特定参数时(在派生类构造中)
class Member {public: explicit Member(int) {} // 无默认构造};
class MyClass { Member m; const int id;public: MyClass(int val, int id) : m(val), id(id) {} // 正确 // MyClass(int val, int id) { m = Member(val); } // 错误:无法先默认构造 m};拷贝构造函数
触发:用同类对象初始化新对象(值传递、按值返回、显式拷贝构造等)。
class Widget {public: Widget(const Widget& other); // 形参必须是引用,否则无限递归};| 拷贝方式 | 行为 | 风险 |
|---|---|---|
| 浅拷贝 | 复制指针值,共享堆内存 | 双重释放、悬垂 |
| 深拷贝 | 复制指针指向的内容 | 安全但可能昂贵 |
含动态资源的类应实现深拷贝,或禁用拷贝(delete)、改用移动语义。
Rule of Three / Five:若自定义析构、拷贝构造、拷贝赋值之一,通常需考虑三者(C++11 起再加移动构造、移动赋值)。
explicit(原笔记空缺,已补充)
阻止隐式单参数转换:
class String {public: explicit String(int size) { /* 分配 size */ }};
// String s = 100; // 错误String s(100); // OKString s{100}; // OK析构函数
- 函数名
~类名(),无参、无返回值、不可重载。 - 对象生命周期结束时自动调用(离开作用域、
delete、临时对象结束等)。 - 未自定义时编译器生成默认析构;对含指针成员仅“浅释放”的类,默认析构不会
delete指针指向的堆内存。
应自定义析构的情况:
new分配的内存- 文件句柄、套接字、锁等需显式释放的资源
多态基类:基类析构函数应声明为 virtual,否则通过基类指针 delete 派生对象时可能只调用基类析构,造成资源泄漏。
struct Base { virtual ~Base() = default;};静态成员
属于类而非某个对象;所有对象共享一份。
class Counter {public: static int count; static void inc() { ++count; }};int Counter::count = 0; // 类外定义(C++17 起 inline 静态成员可在类内初始化)| 类型 | 类内 | 类外 |
|---|---|---|
| 静态数据成员 | 声明 | 定义(除非 inline) |
| 静态成员函数 | 声明/定义 | 无 this,只能直接访问静态成员 |
- 静态成员函数不能访问非静态成员(无
this)。 const整型静态成员可在类内初始化;字符串等非字面量类型等规则见标准(C++17inline变量简化很多场景)。
对象模型与 this
- 类本身不占运行时内存;对象大小由非静态数据成员、对齐、虚表指针等决定。
- 不影响对象大小:静态成员、成员函数(在代码段)。
this:非静态成员函数隐式传入的指针,指向当前对象;类型为T* const(不能改指向别的对象)。- 链式调用:成员函数返回
*this的引用。
class Builder {public: Builder& step1() { /* ... */ return *this; } Builder& step2() { /* ... */ return *this; }};静态成员函数没有 this。
const 与 mutable
const 对象 | const 成员函数 | |
|---|---|---|
| 修改数据成员 | 一般禁止 | 一般禁止 |
| 调用非 const 成员函数 | 禁止 | — |
| 调用 const 成员函数 | 允许 | — |
class Cache { mutable int hits = 0; // 即使在 const 成员函数中也可修改public: int get() const { ++hits; return 42; }};友元
允许指定函数或类访问 private / protected 成员。友元不是成员,不传递、不继承。
| 类型 | 说明 |
|---|---|
| 友元函数 | 普通函数或另一类的成员函数 |
| 友元类 | 整个类的所有成员函数 |
| 友元成员函数 | 只授权另一个类的某个成员函数 |
class B; // 前向声明
class A { friend void show(const A&); friend class B; int secret = 0;};友元关系需在类定义内显式声明;友元类若定义在后,需前向声明。
分享
如果这篇文章对你有帮助,欢迎分享给更多人!
部分信息可能已经过时
相关文章 智能推荐
