1.构造函数
构造函数的特征
+ 名字和类名相同
+ 没有返回值
+ 不写构造函数会存在一个默认的构造函数(无参),如果写了,默认的就不存在
+ 构造函数不需要自己调用,创建对象的时候调用构造函数
+ 构造函数的长相决定了对象模样(参数个数)
+ 构造函数的作用: 一般来说就是为数据做初始化
+ 可以被重载(参数可以不同) ,这样的话可以满足构造不同的对象
namespace myData { class MM { public: MM() { cout << "调用默认构造函数" << endl; } MM(string name) { this->name = name; age = 18; } MM(string name, int age) { this->name = name; this->age = age; } void print() { cout << name << "\t" << age << endl; } protected: string name; int age; }; } int main() { myData::MM* mm = new myData::MM("小可爱"); myData::MM mm1 = { "小李子" };//也是调用构造函数 return 0; }
2.析构函数
+ 函数名是~加上类名
+ 没有返回值
+ 没有参数,所以析构函数只有一个
+ 对象死亡的时候会**自动调用**析构函数
+ 一般都有一个默认的析构,你写了就默认的就不存在
+ 类中数据成员做了动态内存申请,就需要手动写析构
namespace myData { class MM { public: MM() { cout << "调用默认构造函数" << endl; } MM(string name) { this->name = name; age = 18; cout << "调用一个参数构造函数" << endl; } MM(string name, int age) { this->name = name; this->age = age; cout << "调用两个参数构造函数" << endl; } void print() { cout << name << "\t" << age << endl; } ~MM() { cout << "调用了析构函数" << endl; } protected: string name; int age; }; } int main() { myData::MM* mm = new myData::MM("张三",19);//此处先构造无名对象,然后赋值给mm指针,调用了两个参数的构造函数 myData::MM mm1 = { "小李子" };//也是调用构造函数 myData::MM mm2 = myData::MM(); delete mm; /* 结果: 调用两个参数构造函数 (无名对象new一段内存,该段内存不会由析构函数自动释放,应主动释放,delete时调用析构函数) 调用一个参数构造函数 调用默认构造函数 (无名对象构建) 调用了析构函数 调用了析构函数 调用了析构函数 */ return 0;//return后自动析构 }
3.构造顺序与析构顺序
namespace myData { class MM { public: MM() { cout << "调用默认构造函数" << endl; } MM(string name) { this->name = name; age = 18; cout << "调用一个参数构造函数" << endl; } MM(string name, int age) { this->name = name; this->age = age; cout << "调用两个参数构造函数" << endl; } void print() { cout << name << "\t" << age << endl; } ~MM() { cout << name << endl; } protected: string name="@"; int age; }; } void print1(myData::MM obj) { } void print2(const myData::MM& obj) { } void print3(myData::MM* obj) { } int main() { //匿名对象: //正常对象:构造顺序与析构顺序相反 { myData::MM a("A"); myData::MM b("B"); myData::MM c[3]{ {"C",1},{"D",2},{}}; }//在作用域外释放 /* 结果: 调用一个参数构造函数 调用一个参数构造函数 调用两个参数构造函数 调用两个参数构造函数 调用默认构造函数 @ //@表示无名对象 D C B A */ //new一个对象,delete时直接调用析构函数 { myData::MM* a = new myData::MM("A"); myData::MM b("B",19); delete a; a = nullptr; } /* 结果: 调用一个参数构造函数 调用两个参数构造函数 A B */ { myData::MM a("A"); myData::MM("B"); myData::MM c("C"); } /* 结果: 调用一个参数构造函数 调用一个参数构造函数 B //没有管理的匿名对象直接消亡 调用一个参数构造函数 C A */ //匿名对象转交所有权 { myData::MM a("A"); myData::MM b = myData::MM("B");//转正后归对象b管理 myData::MM c("C"); } /* 结果: 调用一个参数构造函数 调用一个参数构造函数 调用一个参数构造函数 C B A */ //匿名对象当作函数参数,不论是赋值还是引用都直接消亡 { print1(myData::MM("A", 20)); print2(myData::MM("B")); print3(new myData::MM()); } /* 结果: 调用两个参数构造函数 A 调用一个参数构造函数 B 调用默认构造函数 */ //静态对象最后被释放 { myData::MM a("A"); static myData::MM b("B",22); myData::MM c; } /* 结果: 调用一个参数构造函数 调用两个参数构造函数 调用默认构造函数 @ A B */ return 0; }