void f(const X& rx, X x)
{
vector<X> vec;
/*vector<int> myVec;
myVec.reserve(100); // 新元素还没有构造, // 此时不能用[]访问元素
myVec.resize(102); // 用元素的默认构造函数构造了两个新的元素
myVec[100] = 1; //直接操作新元素
myVec[101] = 2;*/
vec.reserve(2);//vector 的reserve增加了vector的capacity,但是它的size没有改变!
//而resize改变了vector的capacity同时也增加了它的size!
vec.push_back(rx);//这是才执行创建X类型对象,并拷贝初始化,并执行拷贝构造函数
vec.push_back(x);//这是创建X类型对象,并拷贝初始化,并执行拷贝构造函数
}
int main()
{
//X x1;
//X x2(x1);
//cout << endl;
//X x3,x4;
// x4 = x3;//执行拷贝赋值函数 应该都是已经创建的对象
// cout << endl;
//X x5;
//X x6 = x5;//x6在拷贝初始化的时候才创建 ,且通常使用拷贝构造函数,
// // 所以并不是执行拷贝赋值函数,执行的仍然是拷贝构造函数
/*第一部分执行**/
//X x1;
//X x2;
//f(x1,x2);
//cout << endl;**
/***第二部分执行***/
X *px = new X;
f(*px, *px);
delete px;//如果不加这个 ,因为不是智能指针,
//不能在main结束后(即使px指针没用了)自动销毁px指向对象,那么对象px也不能调用析构函数,
//在第二部分结果就少一次调用析构函数
return 0;
}
第一部分结果::
首先X x1;X x2; 创建两个对象,调用两次构造函数,接着调用函数f(x1,x2);、
因为 f 第一个形参是常量引用所以x1传递未发生事件,第二个正常形参x2会调用拷贝构造函数,接着两次vector.push_back的操作会执行两次拷贝构造函数得到两个X类型的临时局部对象在vector中。接着f完后,首先因为rx是引用所以不会执行析构函数,但x在函数参数是正常的执行拷贝构造函数得来的,所以局部销毁,执行x析构函数,接着vector销毁(也会执行自己的析构函数,但这里没办法打印),也会销毁容器中的两个局部临时X类型对象,接着两个局部临时对象析构函数销毁,最后main函数结束,X1 X2也离开了作用域销毁X1 X2执行两个析构函数,
/// 第二部分也类似,但第二部有一个动态分配内存的X类型对象,main函数结束不会自动执行销毁,只有delete销毁对象,对象才会调用析构函数
第二部分结果: