C++类与对象深度解析(一):从引用、内联函数到构造析构的编程实践
- 游戏开发
- 2025-08-29 03:48:02

目录
一.引用
引用的特征:1.引用必须初始化
2.本质是别名
3.函数参数传递
4.常引用
5.函数返回值
6.权限 放大 缩小 平移
引用 vs 指针
二.内联函数
关键点说明
三.宏函数
四.类
什么是类?
简单的类
五.构造函数与析构函数
1. 构造函数(Constructor)
使用环境:
2. 析构函数(Destructor)
作用
示例
总结
六.this指针
1. 什么是 this 指针?
2. 为什么需要 this 指针?
3. 注意事项
七.拷贝构造函数
一、什么是拷贝构造函数?
二、浅拷贝(Shallow Copy)
什么是浅拷贝?
浅拷贝的问题
三、深拷贝(Deep Copy)
什么是深拷贝?
深拷贝解决方案
四、关键总结
一.引用
引用:引用不是新定义一个量而是给已存变量取一个别名,它和它引用的变量共用一块空间
引用的特征: 1.引用必须初始化引用必须在声明时初始化,且不能重新绑定到其他对象。
int x = 10; int &ref = x; // 正确:引用必须初始化 // int &ref2; // 错误:未初始化的引用 2.本质是别名引用是变量的另一个名字,没有独立的内存地址,操作引用等价于操作原变量。
int x = 10; int &ref = x; // 正确:引用必须初始化 // int &ref2; // 错误:未初始化的引用 3.函数参数传递引用常用于函数参数,避免拷贝开销且允许修改实参(替代指针的简洁语法)。
void swap(int &x, int &y) { int temp = x; x = y; y = temp; } int main() { int a = 1, b = 2; swap(a, b); // 直接传递变量,无需取地址 cout << a << " " << b; // 输出 2 1 } 4.常引用常引用可以绑定到临时对象或字面量,且不能通过引用修改原对象。
const int &r1 = 42; // 正确:常引用可绑定到字面量 int x = 10; const int &r2 = x; // 正确:r2 是 x 的只读别名 // r2 = 20; // 错误:不能通过常引用修改值 5.函数返回值引用可以作为函数返回值,但需确保返回的对象生命周期有效(避免悬空引用)。
int global = 100; int& getGlobal() { return global; // 返回全局变量的引用(安全) } int& dangerous() { int local = 50; return local; // 错误:返回局部变量的引用(悬空引用) } 6.权限 放大 缩小 平移 int main() { //权限不能放大 //const int a = 0; //int& b = a; //可以只是一个拷贝 const int c = 0; int d = c; //引用过程中权限可以平移或者缩小 int x = 0; int& y = x;//权限的平移 const int& z = x;//权限的缩小 ++x;//可以,因为上面是缩小了z的权限 //不可以++z; double dd = 1.11; int ii = dd; // 不可以 int& rii = dd; const int& rii = dd;//临时变量具有常性 return 0; } 引用 vs 指针 特性引用指针初始化必须初始化可以声明后赋值重新绑定不能可以空值不能为空可以为 nullptr内存占用无独立内存地址有自己的内存地址语法简洁性直接操作对象(无需 * 或 ->)需要解引用操作符(* 或 ->) 二.内联函数内联函数建议编译器将函数体直接插入调用位置(类似宏展开),以减少函数调用的开销(压栈、跳转、返回等)。适用于短小且频繁调用的函数。
#include <iostream> // 1. 使用 inline 关键字声明内联函数 inline int add(int a, int b) { return a + b; } // 2. 类内定义的成员函数默认是内联的 class Calculator { public: int multiply(int a, int b) { // 隐式内联 return a * b; } inline int subtract(int a, int b) { // 显式内联 return a - b; } }; int main() { int x = 5, y = 3; // 调用内联函数 add std::cout << "加法结果: " << add(x, y) << std::endl; // 编译器可能直接替换为 x + y Calculator calc; // 调用类内联函数 std::cout << "乘法结果: " << calc.multiply(x, y) << std::endl; std::cout << "减法结果: " << calc.subtract(x, y) << std::endl; return 0; } 关键点说明inline 关键字 用于建议编译器将函数内联,但最终是否内联由编译器决定(可通过编译器优化选项控制,如 -O2)。
类成员函数的内联性
在类内部直接定义的成员函数(如 multiply)默认是内联的。也可以在类外定义成员函数时使用 inline 关键字(需在头文件中实现)。适用场景
函数体短小(如 1-3 行代码)。频繁调用且对性能敏感的场景(如循环中的操作)。注意事项
避免内联复杂函数(如递归函数或包含循环的函数)。内联函数定义必须对调用者可见,通常直接写在头文件中。 三.宏函数优点-- 不需要建立栈帧,提高调用效率 缺点-- 复杂,容易出错、可读性差、不能调试
举例三个问题的宏函数
以
Add(a | b, a & b); // (a | b + a & b)为例: 以下三个有问题:
#define Add(int x, int y) return (x+y); #define Add(x, y) x+y #define Add(x, y) (x+y)原因:(+ 与- 的优先级大于| 与&)
成功示范:
#define Add(x, y) ((x)+(y)) 四.类 什么是类? 类是对象的“蓝图”或“模板”,用于定义对象的属性(成员变量)和行为(成员函数)。通过类可以创建具体的对象(实例),每个对象拥有独立的属性值。类的核心思想是封装:将数据和对数据的操作绑定在一起,并控制外部对数据的访问权限。 简单的类 #include <iostream> using namespace std; // 定义一个 Person 类 class Person { public: // 公有成员,外部可以直接访问 char name; // 成员变量:姓名 int age; // 成员变量:年龄 // 成员函数:显示信息 void display() { cout << "姓名: " << name << ", 年龄: " << age << endl; } }; int main() { // 创建 Person 类的对象 Person person1; // 设置对象的属性 person1.name = "张三"; person1.age = 25; // 调用对象的方法 person1.display(); // 输出:姓名: 张三, 年龄: 25 return 0; }封装:通过 private 隐藏内部细节,通过 public 提供安全接口
五.构造函数与析构函数 1. 构造函数(Constructor)作用
在对象创建时自动调用,用于初始化对象的成员变量。可以重载(定义多个不同参数的构造函数)。没有返回类型,且名称与类名相同。默认构造函数:无参构造函数,全缺省构造函数,编译器默认生成的构造函数
示例
构造函数:
class Person { public: char name; int age; // 默认构造函数(无参数) Person() { name = "Unknown"; age = 0; cout << "默认构造函数被调用" << endl; } // 带参数的构造函数 Person(string n, int a) { name = n; age = a; cout << "带参数的构造函数被调用" << endl; } }; 使用环境: int main() { Person p1; // 调用默认构造函数 Person p2("Alice", 25); // 调用带参数的构造函数 return 0; } 2. 析构函数(Destructor) 作用 在对象销毁时自动调用,用于释放对象占用的资源(如内存、文件句柄)。名称是类名前加 ~,没有参数和返回类型。不能重载(每个类只有一个析构函数)。 示例析构函数:
class FileHandler { private: FILE* file; public: // 构造函数:打开文件 FileHandler(const char* filename) { file = fopen(filename, "r"); cout << "文件已打开" << endl; } // 析构函数:关闭文件 ~FileHandler() { if (file) { fclose(file); cout << "文件已关闭" << endl; } } };使用场景:
int main() { Person p1; // 调用默认构造函数 Person p2("Alice", 25); // 调用带参数的构造函数 return 0; } 总结 特性构造函数析构函数调用时机对象创建时对象销毁时主要用途初始化成员变量释放资源(如内存、文件)重载支持重载(多个构造函数)不支持重载(唯一析构函数)默认生成未定义时编译器生成默认构造函数未定义时编译器生成默认析构函数通过合理使用构造函数和析构函数,可以确保对象在生命周期内正确初始化和清理资源,避免内存泄漏和逻辑错误。
六.this指针 1. 什么是 this 指针?在 C++ 中,this 是一个指向当前对象的指针。
每个类的非静态成员函数(包括构造函数和析构函数)内部都可以访问 this。this 指针是隐式存在的,不需要手动定义。它的类型是 ClassName*(例如,Person*、Car*)。 class Person { public: string name; void printName() { // 实际上等价于:cout << this->name << endl; cout << name << endl; } }; 2. 为什么需要 this 指针?当你在类的成员函数中访问成员变量或调用成员函数时,编译器实际上是通过 this 指针来找到当前对象的成员。 例如:
class Person { public: string name; void printName() { // 实际上等价于:cout << this->name << endl; cout << name << endl; } }; 3. 注意事项this 是一个指针静态函数属于类,而不是对象,因此不能使用 this。this指针是形参所以是存在栈中的
class MyClass { public: static void staticFunc() { // this->xxx; // 错误!静态函数没有 this } }; 七.拷贝构造函数 一、什么是拷贝构造函数?拷贝构造函数是一个特殊的构造函数,用于通过已存在的对象创建一个新对象。当发生以下情况时会自动调用:
用已有对象初始化新对象对象作为函数参数传递(值传递)对象作为函数返回值(值返回)基本语法:
ClassName(const ClassName& other); 二、浅拷贝(Shallow Copy) 什么是浅拷贝? 默认的拷贝构造函数是浅拷贝直接复制成员变量的值(包括指针地址)如果类中有指针成员,会导致多个对象指向同一块内存 浅拷贝的问题 class ShallowCopy { public: int* data; //构造函数 ShallowCopy(int val) { data = new int(val); // 动态分配内存 } // 默认拷贝构造函数是浅拷贝:ShallowCopy(const ShallowCopy& other) = default; //析构函数 ~ShallowCopy() { delete data; // 释放内存 } }; int main() { ShallowCopy obj1(10); ShallowCopy obj2 = obj1; // 浅拷贝 // 问题:obj1和obj2的data指向同一块内存 // 当main结束时,obj2先调用析构函数释放内存 // 然后obj1的析构函数会尝试释放已释放的内存 → 程序崩溃! } 三、深拷贝(Deep Copy) 什么是深拷贝? 需要手动实现拷贝构造函数为指针成员分配新的内存复制指针指向的内容,而不是复制指针地址 深拷贝解决方案 class DeepCopy { public: int* data; DeepCopy(int val) { data = new int(val); } // 手动实现深拷贝构造函数 DeepCopy(const DeepCopy& other) { data = new int(*other.data); // 分配新内存并复制值 } // 注意:还需要重载赋值运算符(规则同理) DeepCopy& operator=(const DeepCopy& other) { if (this != &other) { delete data; // 释放原有内存 data = new int(*other.data); // 深拷贝 } return *this; } ~DeepCopy() { delete data; } }; int main() { DeepCopy obj1(20); DeepCopy obj2 = obj1; // 深拷贝 // obj1.data 和 obj2.data 指向不同内存 // 析构时不会出现重复释放问题 } 四、关键总结 浅拷贝深拷贝复制内容复制指针地址复制指针指向的内容内存安全性多个对象共享同一内存,易导致崩溃每个对象拥有独立内存,安全可靠实现方式默认拷贝构造函数需要手动实现拷贝构造函数适用场景无动态内存分配的简单类有指针成员或动态分配资源的类C++类与对象深度解析(一):从引用、内联函数到构造析构的编程实践由讯客互联游戏开发栏目发布,感谢您对讯客互联的认可,以及对我们原创作品以及文章的青睐,非常欢迎各位朋友分享到个人网站或者朋友圈,但转载请说明文章出处“C++类与对象深度解析(一):从引用、内联函数到构造析构的编程实践”