1.c++编译器会自动调用构造函数
//构造函数(与类名相同)//析构函数:没有参数也没有任何返回类型,被自动调用#include<iostream>using namespace std;class Test{public:Test();//无参构造函数~Test();//析构函数:先创建的对象后释放void print(){cout << a << endl;cout << p << endl;}private:int a;char *p;};Test::Test()//完成对属性的初始化工作{a = 10;p = (char*)malloc(sizeof(100));strcpy(p, "Rita");cout<< "我是构造函数" << endl;}Test::~Test(){if (p != NULL){free(p);}cout << "我是析构函数,我被调用了" << endl;}//给对象搭建一个平台,研究对象的行为void objplay(){//先创建的对象后释放Test t1;t1.print();printf("分隔符\n");Test t2;t2.print();}int main(){objplay();system("pause");return 0;}
分析:先调用t1的无参构造函数,再调用print(),再调用t2的无参构造函数,再调用print(),最后先调用t2的析构函数,因为分配的内存在栈里,先入栈的后出栈,所以先定义的后释放,后调用析构函数。
2.拷贝构造函数的调用(三种方法)
#include<iostream>using namespace std;//类的构造函数的分类:无参构造函数。有参构造函数。拷贝构造函数class Test2{public:Test2()//无参构造函数{m_a = 0;m_b = 0;cout << "无参构造函数" << endl;}Test2(int a){m_a = a;m_b = 0;}Test2(int a, int b){m_a = a; m_b = b;cout << "有参构造函数"<< endl;}//copy构造函数Test2(const Test2& obj){cout << "我也是构造函数"<< endl;}public:void print(){cout << "普通成员函数"<< endl;}private:int m_a;char m_b;};int main04()//调用无参构造函数{Test2 t1;system("pause");return 0;}int main()//调用有参构造函数{//1.括号法Test2 t1(1, 2);//调用参数构造函数,c++编译器自动调用t1.print();//2.=号法Test2 t2 = (1, 2, 3, 4, 5);//= c++对等号符功能增强,c++编译器自动的调用构造函数Test2 t3 = 5;//3.直接调用构造函数,手动的调用构造函数Test2 t4 = Test2(1, 2);//匿名对象的去和留,后面会说t1 = t4;//赋值操作:把t4copy给t1,对象的初始化和对象的赋值是两个不同的概念system("pause");return 0;}
3.拷贝构造函数的调用
#include<iostream>using namespace std;//构造函数的调用class Test4{public:Test4()//无参构造函数{m_a = 0;m_b = 0;cout << "无参构造函数" << endl;}Test4(int a){m_a = a; m_b = 0;}Test4(int a, int b){m_a = a; m_b = b;cout << "有参构造函数" << endl;}//copy构造函数Test4(const Test4& obj){cout << "我也是构造函数" << endl;m_a = obj.m_a + 100;//虽然是拷贝构造函数,也不是完全拷贝,可以根据自己的意愿拷贝(+100)m_b = obj.m_b + 100;}public:void print(){cout << "普通成员函数" << endl;cout << m_a << m_b << endl;}private:int m_a;int m_b;};int main06(){Test4 t1(1, 2);Test4 t0(1, 2);t0 = t1;//不会调用拷贝构造函数//第一种调用方法Test4 t2 = t1;//用t1初始化t2,此时会调用拷贝构造函数t2.print();system("pause");return 0;}//第二种调用时机int main(){Test4 t1(1, 2);Test4 t0(1, 2);Test4 t2(t1);// t1初始化t2,此时会调用拷贝构造函数t2.print();system("pause");return 0;}
4.形参是一个元素,b实参去初始化形参p,会调用copy构造函数
#include<iostream>using namespace std;class Location{public:Location(int xx = 0,int yy=0){X = xx;Y = yy;cout << "Constructor Object\n" << endl;}//copy构造函数完成对象的初始化Location(const Location& obj){X = obj.X;Y = obj.Y;}~Location(){cout << "Destroyed\n" << endl;}int getX(){return X;}int getY(){return Y;}private:int X;int Y;};//形参是一个元素(不是指针也不是引用),当调用此函数时,c++编译器会自动调用copy构造函数,用实参初始化形参void f(Location p){cout << p.getX() << endl;}void playobj(){Location a(1, 2);Location b = a;cout << "对象初始化完毕" << endl;f(b);}int main(){playobj();system("pause");return 0;}
5.关于匿名对象的去和留(匿名对象是否会被析构)
#include<iostream>using namespace std;class Location{public:Location(int xx = 0, int yy = 0){X = xx;Y = yy;cout << "Constructor Object\n" << endl;}//copy构造函数完成对象的初始化Location(const Location& obj){X = obj.X;Y = obj.Y;}~Location(){cout << "Destroyed\n" << endl;}int getX(){return X;}int getY(){return Y;}private:int X;int Y;};//g()函数 返回一个元素//结论1.函数的返回值是一个元素(复杂数据类型),返回的是一个新的匿名对象//如果用匿名对象初始化另一个同类型对象,匿名对象转化成有名对象,不会被析构//如果匿名对象赋值给另一个同类型对象,匿名对象被析构Location g(){Location A(1, 2);return A;//返回一个新的对象,没有名字}void objPlay1(){g();}void objPlay2(){//用匿名对象初始化m,此时c++编译器直接把匿名对象扶正,不会被析构Location m = g();cout << m.getX() << endl;}void objPlay3(){//用匿名对象赋值给m2之后,匿名对象被析构Location m2(1, 2);m2 = g();//这不是初始化,这是赋值cout << m2.getX() << endl;}int main(){//objPlay1();//运行结果1.Constructor Object2.Destroyed3.Destroyed//objPlay2();//运行结果1.Constructor Object2.Destroyed(析构A)3. 1 4.Destroyed(析构m)objPlay3();//运行结果1.Constructor Object(创建m2)2.Constructor Object(创建A)3.Destroyed(析构A)4.Destroyed(析构匿名对象)5. 1 6..Destroyed(析构m2)system("pause");return 0;}