(copy)赋值构造函数的4种调用时机or方法
第一种调用方法:
demo
#include <iostream> using namespace std; class Text { public: Text() // 无参数构造函数 { m_a = 0; m_b = 0; cout << "无参数构造函数" << endl; } Text(int a) // 有参数构造函数 { m_a = a; m_b = 0; cout << "无参数构造函数" << endl; } Text(int a, int b) // 有参数构造函数,有三种调用方法 { m_a = a; m_b = b; cout << "有参数构造函数" << endl; } // 赋值构造函数,也叫copy构造函数 Text(const Text& obj) { cout << "这也是构造函数" << endl; } ~Text(); void printT() { cout << "普通成员函数" << endl; cout << "m_a" << m_a << " m_a" << m_b << endl; } private: int m_a; int m_b; }; // 1 赋值构造函数,用1个对象去初始化另外一个对象 int main() { Text t1(1, 2); Text t0(1, 2); // 赋值 = 操作,不会调用构造函数 t0 = t1; // 用t1给t0赋值,和初始化是两个不同的概念 // 第一种调用时机 Text t2 = t1; // 用t1来初始化t2 t2.printT; return 0; }
第二种调用方法:
demo
// 第二种调用方法 int main() { Text t1(1, 2); Text t0(1, 2); Text t2(t1); // 用t1对象初始化t2对象 t2.printT(); return 0; }
第三种调用方法:
demo
<pre name="code" class="cpp">#include <iostream> using namespace std; class Location { public: Location(int xx = 0, int yy = 0) { X = xx; Y = yy; cout << "Constructor Object.\n"; } // copy构造函数,完成对象的初始化 Location(const Location & obj) { X = obj.X; Y = obj.Y; } ~Location() { cout << X << "," << Y << " Object destroyed." << endl; } int getX() { return X; } int getY() { return Y; } private: int X, Y; }; // 业务函数,形参是一个元素 void f(Location p) { cout << p.getX() << endl; } void playObj() { Location a(1, 2); Location b = a; cout << "b对象已经初始化完毕" << endl; // 可以设置断点看函数的调用跳转 f(b); // b实参去初始化形参p,会调用copy构造函数 } int main() { playObj(); return 0; }
第四种调用方法:
demo
#include <iostream> using namespace std; class Location { public: Location(int xx = 0, int yy = 0) { X = xx; Y = yy; cout << "Constructor Object.\n"; } // copy构造函数,完成对象的初始化 Location(const Location & obj) { X = obj.X; Y = obj.Y; } ~Location() { cout << X << "," << Y << " Object destroyed." << endl; } int getX() { return X; } int getY() { return Y; } private: int X, Y; }; //g函数返回一个元素 //结论1 : 函数的返回值是一个元素 (复杂类型的), 返回的是一个新的匿名对象(所以会调用匿名对象类的copy构造函数) // //结论2: 有关 匿名对象的去和留 //如果用匿名对象,初始化另外一个同类型的对象, 匿名对象,转成有名对象 //如果用匿名对象,赋值给另外一个同类型的对象, 匿名对象,被析构 // //这么写代码,设计编译器的大牛们: //就返回一个新对象(没有名字 匿名对象) Location g() { Location A(1, 2); return A; } // void objplay2() { g(); } // void objplay3() { //用匿名对象初始化m,此时c++编译器,直接把匿名对转成m;(扶正),从匿名转成有名字了m Location m = g(); printf("匿名对象,被扶正,不会析构掉\n"); cout << m.GetX() << endl;; } void objplay4() { //用匿名对象,赋值给m2后,匿名对象被析构 Location m2(1, 2); m2 = g(); printf("因为用匿名对象=给m2, 匿名对象,被析构\n"); cout << m2.getX() << endl;; }