1124 字
3 分钟
【CPP】类
2026-03-24

整理自 0319、0320、0323、0324 相关章节,已校对并补充。

类与对象#

  • :类型的蓝图,描述属性(成员变量)与行为(成员函数)。
  • 对象:类的实例。

访问控制#

关键字类内派生类类外
public
protected
private
  • 默认成员访问权限为 privatestruct 默认为 public)。
  • 访问说明符作用到下一个说明符或类结束
class Demo {
int num; // private
public:
void setNum(int v);
};
void Demo::setNum(int v) {
this->num = v; // 成员函数内可用 this
}

类外定义成员函数#

class Stock {
public:
void set_tot();
};
// 类内声明、类外定义;若在类外定义且希望内联,可加 inline
inline 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); // OK
String 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++17 inline 变量简化很多场景)。

对象模型与 this#

  • 类本身不占运行时内存;对象大小由非静态数据成员、对齐、虚表指针等决定。
  • 不影响对象大小:静态成员、成员函数(在代码段)。
  • this:非静态成员函数隐式传入的指针,指向当前对象;类型为 T* const(不能改指向别的对象)。
  • 链式调用:成员函数返回 *this 的引用。
class Builder {
public:
Builder& step1() { /* ... */ return *this; }
Builder& step2() { /* ... */ return *this; }
};

静态成员函数没有 this

constmutable#

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;
};

友元关系需在类定义内显式声明;友元类若定义在后,需前向声明。

分享

如果这篇文章对你有帮助,欢迎分享给更多人!

【CPP】类
https://lysj.work/posts/studynotes/cpp/cpp类/
作者
Sekiro
发布于
2026-03-24
许可协议
CC BY-NC-SA 4.0

部分信息可能已经过时

目录