021 C++的class
0. class 特性一览
分类维度 | 成员类型 | 说明 | 示例 | 访问权限 | 是否可继承 | 是否可虚化 | 初始化方式 |
---|---|---|---|---|---|---|---|
基础类型 | 数据成员 | 存储对象状态的变量 | int value; | 任意(public等) | 是 | 否 | 构造函数或初始化列表 |
成员函数 | 定义对象行为的函数 | void print() { ... } | 任意 | 是 | 是(虚函数) | 无需初始化 | |
静态性 | 静态数据成员 | 类级别共享的变量 | static int count; | 任意 | 否 | 否 | 类外初始化(.cpp文件) |
非静态数据成员 | 实例级别的变量 | std::string name; | 任意 | 是 | 否 | 构造函数或初始化列表 | |
静态成员函数 | 无this 指针,只能访问静态成员 | static void log() { ... } | 任意 | 否 | 否 | 无需初始化 | |
访问权限 | public成员 | 任意位置可访问 | public: int id; | public | 是 | - | - |
protected成员 | 仅限类内和派生类访问 | protected: double rate; | protected | 是 | - | - | |
private成员 | 仅限类内访问 | private: int secretCode; | private | 否 | - | - | |
特殊成员函数 | 构造函数 | 对象初始化逻辑 | ClassName(int x) : value(x) {} | 任意(通常public) | 否 | 否 | 自动调用 |
析构函数 | 资源释放逻辑 | ~ClassName() { delete ptr; } | 通常public | 是(虚析构函数) | 是 | 自动调用 | |
拷贝构造函数 | 深拷贝控制 | ClassName(const ClassName& other); | 通常public | 是 | 否 | 显式或隐式调用 | |
移动构造函数 (C++11) | 资源转移优化 | ClassName(ClassName&& other) noexcept; | 通常public | 是 | 否 | 显式调用(std::move 触发) | |
拷贝赋值运算符 | = 操作符重载 | ClassName& operator=(const ClassName&); | 通常public | 是 | 否 | 显式调用 | |
移动赋值运算符 (C++11) | 移动语义优化 | ClassName& operator=(ClassName&&) noexcept; | 通常public | 是 | 否 | 显式调用 | |
虚函数特性 | 虚函数 | 支持动态多态 | virtual void draw() const; | 通常public/protected | 是 | 是 | 通过派生类覆盖 |
纯虚函数 | 定义接口规范 | virtual void serialize() = 0; | 通常public | 是 | 是 | 必须在派生类实现 | |
CV限定 | const成员函数 | 承诺不修改对象状态 | int get() const { return value; } | 任意 | 是 | 是(可虚化) | - |
volatile成员函数 | 处理易变数据 | void update() volatile { ... } | 任意 | 是 | 是 | - | |
其他特性 | mutable成员 | 允许在const函数中修改 | mutable int cache; | 任意 | 是 | 否 | 常规初始化 |
友元声明 | 授权外部访问私有成员(非类成员) | friend class FriendClass; | 仅类内声明 | 否 | 否 | - | |
内联成员函数 | 编译器展开优化 | inline void calc() { ... } | 任意 | 是 | 是 | - | |
constexpr成员函数 (C++11) | 编译时计算能力 | constexpr int size() { return N; } | 任意 | 是 | 否 | - | |
模板成员函数 | 泛型编程支持 | template<typename T> void process(T); | 任意 | 是 | 否 | - | |
运算符重载 | operator重载 | 自定义操作符行为 | bool operator==(const ClassName&); | 通常public | 是 | 是(可虚化) | - |
类型成员 | 嵌套类型 | 类内定义的类型(enum/class/typedef) | using Iterator = std::vector<T>::iterator; | 任意 | 是 | 否 | - |
关键补充说明:
存储位置:
- 静态成员:全局数据区(生命周期与程序相同)
- 非静态成员:对象内存空间(栈/堆)虚函数表:
- 虚函数和纯虚函数通过虚函数表(vtable)实现动态绑定现代C++扩展:
-noexcept
修饰符(C++11):移动操作的异常规范
-override
/final
限定符(C++11):显式控制继承行为
- 委托构造函数(C++11):复用构造函数逻辑特殊规则:
- 静态常量整型成员可在类内直接初始化:static const int MAX = 100;
- 虚函数不能是静态成员函数
- 友元函数/类不属于类的成员,但拥有访问权限
以下是一个综合示例代码,展示表格中提到的C++类成员特性。代码包含详细注释说明各个知识点:
1
#include <iostream>
2
#include <string>
3
#include <vector>
4
5
class Entity {
6
// 访问权限分类
7
public:
8
// 基础类型:数据成员 + 成员函数
9
int id; // 公有数据成员
10
void display() const { // const成员函数(CV限定)
11
std::cout << "ID: " << id
12
<< ", Name: " << name // 访问私有成员(通过公有接口)
13
<< ", Cache: " << cache // mutable成员可修改
14
<< "\n";
15
cache = 0; // 允许在const函数中修改mutable成员
16
}
17
18
// 特殊成员函数:构造函数系列
19
Entity(int id, std::string name) // 普通构造函数
20
: id(id), name(name), cache(0) { // 初始化列表
21
++count; // 访问静态成员
22
}
23
24
Entity(const Entity& other) // 拷贝构造函数
25
: id(other.id), name(other.name), cache(other.cache) {
26
std::cout << "Copy constructor called\n";
27
}
28
29
Entity(Entity&& other) noexcept // 移动构造函数(noexcept C++11)
30
: id(std::move(other.id)),
31
name(std::move(other.name)),
32
cache(std::exchange(other.cache, 0)) {
33
std::cout << "Move constructor called\n";
34
}
35
36
// 运算符重载
37
Entity& operator=(const Entity& rhs) { // 拷贝赋值运算符
38
if (this != &rhs) {
39
id = rhs.id;
40
name = rhs.name;
41
cache = rhs.cache;
42
}
43
return *this;
44
}
45
46
bool operator==(const Entity& other) const { // 运算符重载(比较操作)
47
return id == other.id && name == other.name;
48
}
49
50
// 虚函数特性
51
virtual ~Entity() { // 虚析构函数(支持多态销毁)
52
--count;
53
std::cout << "Entity destroyed\n";
54
}
55
56
virtual void serialize() const { // 虚函数
57
std::cout << "Serializing base entity\n";
58
}
59
60
virtual void update() = 0; // 纯虚函数(接口规范)
61
62
// 静态成员
63
static int count; // 静态数据成员
64
static void logCount() { // 静态成员函数
65
std::cout << "Total entities: " << count << "\n";
66
}
67
68
// 类型成员
69
enum class State { Active, Inactive }; // 嵌套枚举类型
70
using Container = std::vector<Entity>; // 类型别名(C++11 using)
71
72
// 模板成员函数
73
template <typename T>
74
void process(T value) { // 模板成员函数
75
std::cout << "Processing: " << value << "\n";
76
}
77
78
// constexpr成员函数(C++11)
79
constexpr int getCache() const { return cache; }
80
81
protected:
82
std::string name; // 受保护数据成员
83
84
private:
85
// 私有成员与友元
86
mutable int cache; // mutable成员
87
friend void debugEntity(const Entity&); // 友元函数
88
};
89
90
// 静态成员初始化(必须在类外)
91
int Entity::count = 0;
92
93
// 友元函数实现
94
void debugEntity(const Entity& e) {
95
std::cout << "[DEBUG] Private cache: " << e.cache << "\n"; // 访问私有成员
96
}
97
98
// 派生类演示继承和多态
99
class Player : public Entity {
100
public:
101
Player(int id, std::string name, int level)
102
: Entity(id, name), level(level) {}
103
104
// override显式声明(C++11)
105
void serialize() const override {
106
std::cout << "Serializing player (level " << level << ")\n";
107
}
108
109
void update() override { // 实现纯虚函数
110
std::cout << "Updating player...\n";
111
}
112
113
// final阻止进一步重写(C++11)
114
void finalMethod() final {}
115
116
private:
117
int level;
118
};
119
120
int main() {
121
// 静态成员使用
122
Entity::logCount();
123
124
// 对象构造与初始化
125
Entity e1(1, "Test");
126
e1.display();
127
e1.process(3.14); // 模板成员函数调用
128
129
// 拷贝/移动语义
130
Entity e2 = e1; // 调用拷贝构造函数
131
Entity e3 = std::move(e1); // 调用移动构造函数
132
133
// 多态演示
134
Player p1(100, "Hero", 10);
135
Entity* entity = &p1;
136
entity->serialize(); // 动态绑定
137
entity->update();
138
139
// 运算符重载
140
if (e2 == e3) {
141
std::cout << "Entities are equal\n";
142
}
143
144
// 类型成员使用
145
Entity::State state = Entity::State::Active;
146
Entity::Container entities;
147
entities.emplace_back(2, "Object");
148
149
// 友元函数调用
150
debugEntity(p1);
151
152
// 静态成员访问
153
std::cout << "Final entity count: " << Entity::count << "\n";
154
}
该代码演示了以下核心知识点:
1. 访问权限控制(public/protected/private)
2. 构造函数系列(普通/拷贝/移动)
3. 运算符重载(=, ==)
4. 虚函数与纯虚函数(多态实现)
5. 静态成员及其初始化
6. 模板成员函数
7. const成员函数和mutable成员
8. 友元函数访问私有成员
9. 类型成员(枚举、using别名)
10. 现代C++特性(noexcept, override, final)
11. 对象生命周期管理(析构函数调用)
12. 动态多态(通过基类指针调用派生类方法)
编译运行时会依次展示:
- 对象构造/拷贝/移动过程
- 多态方法调用
- 运算符重载比较
- 静态成员计数变化
- 友元函数访问私有成员
- 模板函数实例化等特性
可以通过观察输出顺序和数值变化,直观理解各个类成员的工作机制。
一、类的基本概念
1.1 类定义
1
class ClassName {
2
// 访问说明符
3
private:
4
// 私有成员(数据+方法)
5
protected:
6
// 受保护成员
7
public:
8
// 公共成员
9
// 构造函数
10
// 析构函数
11
// 成员函数
12
};
1.2 访问控制
访问级别 | 说明 |
---|---|
private | 仅类内成员和友元可访问(默认) |
protected | 类内、派生类和友元可访问 |
public | 任何代码均可访问 |
1.3 成员函数
- 内联定义:直接在类内实现
- 外部定义:使用
ClassName::methodName()
语法
1
class Rectangle {
2
public:
3
int area() { return width * height; } // 内联
4
void setDimensions(int w, int h);
5
};
6
7
void Rectangle::setDimensions(int w, int h) {
8
width = w;
9
height = h;
10
}
二、对象实例化
2.1 创建对象
1
ClassName obj; // 栈上分配
2
ClassName *objPtr = new ClassName(); // 堆上分配
2.2 this指针
- 指向当前对象实例的指针
- 用于区分成员变量和参数
1
void ClassName::setValue(int value) {
2
this->value = value;
3
}
三、构造函数与析构函数
3.1 构造函数类型
类型 | 说明 | 示例 |
---|---|---|
默认构造函数 | 无参数 | ClassName() {} |
参数化构造函数 | 带初始化参数 | ClassName(int a, int b) {} |
拷贝构造函数 | 对象复制 | ClassName(const ClassName &obj) {} |
委托构造函数 | C++11特性,复用其他构造函数 | ClassName() : ClassName(0,0) {} |
3.2 初始化列表
1
ClassName::ClassName(int a, int b) : memberA(a), memberB(b) {}
3.3 析构函数
1
~ClassName() {
2
// 释放资源
3
}
四、静态成员
4.1 静态变量
- 类所有实例共享
- 必须在类外初始化
1
class MyClass {
2
public:
3
static int count;
4
};
5
int MyClass::count = 0;
4.2 静态函数
- 只能访问静态成员
- 通过类名调用
1
class MyClass {
2
public:
3
static void showCount() {
4
cout << count;
5
}
6
};
五、友元机制
5.1 友元函数
1
class MyClass {
2
private:
3
int secret;
4
friend void friendFunction(MyClass &obj);
5
};
6
7
void friendFunction(MyClass &obj) {
8
obj.secret = 10; // 访问私有成员
9
}
5.2 友元类
1
class FriendClass {
2
friend class MyClass;
3
// MyClass可访问FriendClass的私有成员
4
};
六、运算符重载
6.1 基本语法
1
ReturnType operatorOP(ParameterList) {
2
// 实现
3
}
6.2 常见运算符重载
1
// 加法运算符
2
ClassName operator+(const ClassName &obj) {
3
ClassName temp;
4
temp.value = this->value + obj.value;
5
return temp;
6
}
7
8
// 输入输出流
9
friend ostream& operator<<(ostream &os, const ClassName &obj);
七、继承
7.1 继承类型
继承方式 | 基类public成员 | 基类protected成员 |
---|---|---|
public | 保持public | 保持protected |
protected | 变为protected | 保持protected |
private | 变为private | 变为private |
7.2 派生类定义
1
class Derived : access-specifier Base {
2
// 新增成员
3
};
7.3 虚函数与多态
1
class Base {
2
public:
3
virtual void show() { cout << "Base"; }
4
};
5
6
class Derived : public Base {
7
public:
8
void show() override { cout << "Derived"; }
9
};
八、高级特性
8.1 虚析构函数
1
virtual ~Base() {}
8.2 纯虚函数与抽象类
1
virtual void func() = 0; // 抽象类至少包含一个纯虚函数
8.3 移动语义(C++11)
1
ClassName(ClassName&& other) noexcept; // 移动构造函数
2
ClassName& operator=(ClassName&& other) noexcept; // 移动赋值
九、设计原则
- 封装性:隐藏实现细节
- 单一职责原则:一个类只做一件事
- RAII:资源获取即初始化
- Liskov替换原则:派生类应可替代基类
十、代码示例
1
class Animal {
2
protected:
3
string name;
4
public:
5
Animal(string n) : name(n) {}
6
virtual void speak() = 0; // 纯虚函数
7
};
8
9
class Dog : public Animal {
10
public:
11
Dog(string n) : Animal(n) {}
12
void speak() override {
13
cout << name << " says Woof!";
14
}
15
};
注意事项
- 遵循三/五法则:如果定义了析构函数/拷贝控制函数,通常需要全部定义
- 优先使用初始化列表进行成员初始化
- 多态基类应声明虚析构函数
- 避免返回内部成员的引用/指针
通过系统学习以上内容,可以掌握C++类的核心机制与高级特性,为面向对象编程打下坚实基础。建议配合实际项目练习,加深理解。