/*
copy构造函数的调用 时机1 时机2
*/
#if 1
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) //有参数构造函数 //3种方法
{
m_a = a;
m_b = b;
cout << "有参数构造函数" << endl;
}
//赋值构造函数 (copy构造函数) 作用完成对象的初始化
Test4(const Test4& obj)
{
cout << "我也是构造函数,我是通过另一个对象obj来初始化我自己 " << endl;
m_a = obj.m_a + 100;
m_b = obj.m_b + 100;
}
~Test4()
{
cout << "我是析构函数,自动被调用了" << endl;
}
public:
void printT()
{
cout << "普通成员函数" << endl;
cout << "m_a = " << m_a << ", m_b = " << m_b << endl;
}
private:
int m_a;
int m_b;
};
void test()
{
//赋值构造函数 用一个对象初始化另一个对象
Test4 t1(10, 12);
Test4 t0(0, 2);
//赋值操作 和 初始化是两个不同的概念
//赋值 = 操作 不会调用拷贝构造函数,编译器给我们提供的浅copy
t0 = t1; //用t1 给 t0赋值
//第一种 调用拷贝构造函数的时机
Test4 t2 = t1; //用t1来初始化t2,调用t2这个对象的拷贝构造函数
t2.printT();
//第二种 调用拷贝构造函数的时机
Test4 t3(t1); //用t1来初始化t2
t3.printT();
}
#endif
/*
赋值构造函数的调用 时机3
*/
#if 1
class Location
{
public:
//构造函数
Location(int xx = 0, int yy = 0)
{
X = xx;
Y = yy;
cout << "Constructor Object." << endl;
}
//拷贝构造函数 完成对象的初始化
Location(const Location &obj)
{
X = obj.X;
Y = obj.Y;
cout << "copy 构造函数." << endl;
}
~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 test()
{
Location a(1, 2);
Location b = a; //第一种 调用拷贝构造函数的时机
/*
实参b去初始化形参p,c++编译器会调用形参 p 这个对象的copy构造函数,
由于p是局部变量,函数f()运行完毕,p对象的生命周期结束,会调用
p对象的析构函数。
先创建的对象后释放
*/
//b实参去初始化形参p,会调用copy构造函数
cout << "-------1------" << endl;
f(b); //第3种时机
cout << "-------2------" << endl;
cout << "b对象已经初始化完毕" << endl;
}
#endif
/*
赋值构造函数的调用 时机4
*/
#if 1
class Location
{
public:
//构造函数
Location(int xx = 0, int yy = 0)
{
X = xx;
Y = yy;
cout << "Constructor Object." << endl;
}
//拷贝构造函数 完成对象的初始化
Location(const Location &obj)
{
X = obj.X;
Y = obj.Y;
cout << "copy Constructor Object." << endl;
}
~Location()
{
cout << X << "," << Y << " Object destroyed." << endl;
}
int GetX() { return X; } int GetY() { return Y; }
private:
int X, Y;
};
//第4种 调用拷贝构造函数的时机
Location g()
{
Location A(11, 22);//执行对象A的构造函数
return A;
/*
return A;
这条语句 首先会创建一个匿名对象,用对象A初始化匿名对象,执行匿名对象的copy构造函数,
然后对象A的生命周期结束了,会执行对象A的析构函数。g()返回一个匿名对象.
*/
}
//测试匿名对象的生命周期
void objplay2()
{
g();//g()返回一个匿名对象,如果匿名对象没人接,则会执行匿名对象的析构函数。
}
运行结果(测试匿名对象的生命周期)
/*
g()函数 返回一个元素
结论 1:函数的返回值是一个元素(复杂类型的),返回一个新的匿名对象(所以会调用匿名对象
的 copy构造函数)。
结论 2:有关匿名对象的去和留
如果用匿名对象 初始化 另一个同类型的对象,匿名对象转化为有名对象,匿名对象不会被析构掉
如果用匿名对象 赋值给 另一个同类型的对象,匿名对象被析构
*/
void objplay3()
{
//用匿名对象初始化m,此时c++编译器直接把匿名对象转成m(扶正),从匿名转成有名对象了m
Location m = g();
printf("匿名对象,被扶正,不会被析构掉\n");
cout << m.GetX() << endl;
}
运行结果(函数返回的匿名对象的去初始化另一个对象)
void objplay4()
{
Location m2(1, 2);
m2 = g();//用匿名对象 赋值给 m2
printf("因为用 匿名对象 赋值 给m2, 匿名对象被析构\n");
cout << m2.GetX() << endl;
}
运行结果(函数返回的匿名对象的去赋值另一个对象)
、
void objplay5()
{
//用匿名对象 赋值给 m2
Location m1(1, 2);
cout << "------1-----" << endl;
m1 = Location(33, 44); //赋值操作 Location(33, 44)会产生匿名对象,匿名对象被析构
cout << "------2-----" << endl;
Location m2 = Location(55, 66);//初始化操作 Location(55, 66)会产生匿名对象,匿名对象转正,不会被析构
cout << "------3-----" << endl;
}
运行结果:
void objplay6()
{
Location(77, 88); //直接调用构造函数,会产生匿名对象,临时匿名对象的生命周期
cout << "------1-----" << endl;
}
void test()
{
//objplay2();
//objplay3();
//objplay4();
//objplay5();
objplay6();
}
#endif