C++的构造函数和析构函数用于对象的初始化和清理,每个类定义的时候会默认创建三个函数——构造函数,析构函数,拷贝构造函数
1.默认构造函数
构造函数类似于python的__init__方法,在类被实例出一个对象的时候自动调用,且只调用一次,默认的构造函数没有参数且内容为空,可以通过重写修改默认构造函数,重写方式为 类名(参数){}, 构造函数和普通函数一样,可以重载,所以一个类里可以有多个构造参数,实例初始化时会根据传参情况自动识别调用。
#include <iostream> using namespace std; #include <string> class PersonTest { string name; public: //注意析构函数必须是公有方法 构造看情况 // 构造函数 类似于init // 多个函数类似于重载,自动识别调用 PersonTest() { cout << "默认无参数构造函数的调用" << endl; } PersonTest(string name1) { cout << "有参构造函数的调用" << endl; name = name1; cout << name << endl; } }; int main() { PersonTest p1; string name = "name1"; PersonTest p2(name); PersonTest p3("name2"); system("pause"); return 0; }
在main函数中实例化对象(使用括号法 ),输入结果如下:
此处在初始化实例对象时,会根据你传入的参数类型调用相应的构造函数;
2. 拷贝构造函数
拷贝构造函数的参数是一个实例化的对象的引用 类名(const 类名 &对象){ }, 该函数的作用在于将传入的实例对象复制出另一个一样的对象,两个对象拥有相同的属性。 默认的拷贝构造函数是将传入实例的所有属性完全复制,重写拷贝构造函数后,可以复制指定属性。
//拷贝构造函数 函数值传递的时候会自动调用拷贝构造函数, 函数返回对象也是调用拷贝函数 创建 值传递 值返回 PersonTest(const PersonTest & p) { cout << "拷贝构造函数调用" << endl; name = p.name; cout << name << endl; }
在实例化对象时,传入一个已经创建的对象,拷贝构造函数会自动调用:
输出结果为:
拷贝构造函数在三种情况下会调用: 1利用已有实例复制创建新实例,2 将实例作为函数的形参, 3 将实例作为函数的返回值
3. 析构函数
析构函数类似于python中的__del__函数,在实例对象被销毁的时候调用;默认的析构函数参数为空,内容为空析构函数重写方式为 ~类名(){} ;注意析构函数不可重载;
// 析构函数 类似于 del方法 不可重载 ~PersonTest() { cout << name << endl; cout << "析构函数调用" << endl; }
析构函数必须为公共方法,否则实例销毁时,系统调用会出错;
4. 创建对象的几种方法
1.括号法 2.显示法 3.隐式转换法
此处直接上代码
int main() { //括号法 PersonTest p1; string name = "name1"; PersonTest p2(name); PersonTest p3("name2"); // 拷贝构造函数 PersonTest p03(p3); //显示法 PersonTest p4; //无参情况三种方法都是一样的 PersonTest p5 = PersonTest(name); PersonTest p6 = PersonTest("name2"); PersonTest p7 = PersonTest(p6); //隐式转换法 PersonTest p8; PersonTest P9 = name; // PersonTest P9 = "name"; 这么写会报错, 因为C++默认一串未定义字符串为char[]型 使用cout << typeid("name").name() << endl;查看变量类型 PersonTest P10 = P9; system("pause"); return 0; }
需要注意的有以下几点:
1 隐式转换时,由于构造函数参数类型为string,所以不能使用 PersonTest P9 = "name"; 这么写会报错, 因为C++默认一串未定义字符串为char[]型 使用cout << typeid("name").name() << endl;查看变量类型;可以先用 string name = "name"定义,然后用name传参;
2 显示法书写时 PersonTest(name); 其实是一个匿名对象,如果不给匿名对象左值,则该条语句执行时会创建一个实例对象,并且在该行执行完毕后销毁对象;尤为注意不要利用拷贝构造函数初始化匿名对象;如PersonTest(p6), 会报错重定义; 编译器会认为是对象p6的声明;