C++ ———— 2(类相关)
一、类——class
类:
是对象的抽象,对象是实例化的对象
对象:
对象要占内存空间,类不会占内存空间
类的一般形式
class { public: //公有区域 protected: //保护区域 private: //私有区域 }
类实例化的方法:
类名 对象名; //栈区对象 类名 指针名 = new 类名; //堆区对象
二、构造函数
构造函数结构
class 类名{ public: /** 构造函数: 1.无返回值 2.定义时,系统自动调用 3.不能手动调用构造函数 4.如果没有实现构造函数,编译器会自动生成一个无参构造 */ 类名(参数) { 函数体 } }
构造函数参数传递
List obj(20); //显式传递参数给构造函数 List obj2 = 20; //隐式传递参数 List *p = new List(20); //正常传递参数给构造函数
三、析构函数
析构函数:
专门用来回收对象的资源,函数名和类名一致,在函数名前加~
特征:
没有返回值、没有参数、无法重载
可以手动调用析构函数,也可以在生命周期结束时被系统自动调用(注意double free)
~List() { if(nullptr != p) //注意判断要delete的空间是否已经被释放 { //避免造成double free delete[] p; p = nullptr; } }
析构函数问题
析构函数是释放资源时自动调用,在如下代码中,代码的执行是在系统栈区内的,所以将对象进行压栈处理,这就使最后释放资源调用析构函数的时候的顺序有所改变(遵循栈的先进后出原则)
class A { public: A(int a) { cout << "A" << a << endl; this->num = a; } //普通构造函数 ~A() { cout << "~A" << this->num << endl; } //析构函数 private: int num; }; int main() { A a(10); A b(20); return 0; }
四、特殊构造——拷贝构造
新构造对象的时候,初始化的等式右值为已存在的同类型对象,系统会调用拷贝构造函数
List b = a; //a为已存在的List对象,b为新对象
拷贝构造
仍然是构造函数,我们没有声明实现,编译器会自动生成
,自动生成的拷贝构造函数是直接对已存在对象的数值依次赋值
给新对象(浅拷贝)当类中有
new
出来的成员就会出现double free
问题,此时我们必须要重新实现拷贝构造进行深拷贝
。//拷贝构造eg List(const List &obj) { this.index = obj.index; this.max = obj.max; this.arr = new Type[max]; for(int i = 0 ; i < this.index ; i++ ) this.arr[i] = obj.arr[i]; }
五、特殊构造——移动构造
C++ 11 中新的语法,如果给一个新对象赋值临时对象,此时会调用移动构造来实现。
移动构造形式:
类名(类名 &&obj) { //移动构造 }
g++编译器 默认会优化掉 临时对象 ,所以一般不会用到移动构造
六、临时对象的问题
函数返回的对象、无名对象都是临时对象。
C++默认禁止临时对象产生,如果需要允许临时对象产生,需要添加编译开关:
g++ xxx.cpp -fno-elide-constructors
七、static成员
静态成员属于class类 不属于对象
可以将类的成员声明成静态的(关键字static修饰的成员函数或成员变量)
通过类名和作用域解析运算符来调用静态成员
类名:静态成员名称
静态成员没有对象的this指针
静态成员不和具体的对象关联,也不能直接访问类的其他成员
static修饰成员变量
:它仍然受到类的访问权限限制,初始化只能在类外
static修饰成员函数
:它仍然受到类的访问权限限制,静态成员函数只能访问静态成员。
八、const成员变量
1.const修饰成员变量
const作用:
常量化
const修饰成员数据:
表示类的成员数据只读
const成员数据(初始化):
只能使用初始化列表来初始化(初始化列表只在构造函数内可用)class A { public: A(){} A(int a):val(val),b(a) //:val(a) 初始化列表 只在构造函数内有这个语法 在构造函数调用之前进行赋值操作 { //this->val = val; //error val是const修饰的不能被修改 } private: const int val; int b; }
2.const修饰成员函数
const修饰类的成员函数:
表示该函数不会修改类的成员数据
一般形式:
返回值类型 成员函数名(形参列表) const { //函数体 }
<tips>
const修饰的成员函数内部不能修改成员数据,内部也不能调用类的非const成员函数3.const修饰类对象
const修饰类对象:
表示该对象是常对象
常对象:
只能访问常成员
一般形式:
const 类型 对象名; 类名 const 对象名;
练习:
编写一个类,用一个成员变量实现统计实例对象个数。
源码
*=============================================== * 文件名称:work1.cpp * 创 建 者:青木莲华 * 创建日期:2025年08月27日 * 描 述:使用static成员变量,统计实例对象个数 ================================================*/ #include <iostream> using namespace std; class A { public: A() { this->obj_count++; cout << "new Object" << endl; out_count(); } ~A() { this->obj_count--; cout << "delete Object" << endl; out_count(); } void out_count() { cout << "count = " << this->obj_count << endl; } private: static int obj_count; }; //初始化 静态变量 int A::obj_count = 0; int main() { A a; A b; A c; A d; }
运行截图