使用匿名对象初始化数组时,析构函数显示有效值,但是我创建了一个包含对象的数组,重写副本构造函数未调用,析构函数也显示垃圾值。
我试图通过显示值来理解这一点,但仍然感到困惑。
class Check{
private:
int a;
public:
Check()
{
this->a = 9999;
cout << "\n Default Constructor Called \n";
}
Check(int i)
{
this->a = i;
}
Check(const Check & obj)
{
cout << "COPY CONSTRUCTOR\n";
}
~Check()
{
cout << this->a<<" DESTRUCTOR \n";
}
};
Check b[2] = {Check(5),Check(4)};
Check obj1(2);
Check obj2(3);
Check a[2] = {obj1,obj2};
我期望“ COPY CONSTRUCTOR”输出4倍,但是只有2倍,没有垃圾值。实际输出如下:
COPY CONSTRUCTOR COPY CONSTRUCTOR 32649 DESTRUCTOR -1330935392 DESTRUCTOR 3 DESTRUCTOR 2 DESTRUCTOR 4 DESTRUCTOR 5 DESTRUCTOR
答案 0 :(得分:2)
原因是由于复制省略。
在这种情况下:
Check b[2] = {Check(5),Check(4)};
由于两个值都是临时值,因此允许编译器(或在C ++ 17中为强制执行)优化副本并改为就地构造对象。
但是,在第二种情况下:
Check a[2] = {obj1,obj2};
obj1
和obj2
不是临时的,因此在这种情况下必须出现真实的副本。
答案 1 :(得分:2)
在:
Check b[2] = {Check(5),Check(4)};
此语法意味着两个数组元素的构造函数参数为5
和4
。这并不意味着参数是临时的。
Check(5)
是一个 prvalue表达式,这不一定意味着一个临时实例已实现。可以使用prvalue的一种方式是将其用作同一类型对象的初始化程序。
此行为在C ++ 17中已更改;在此之前,概念上总是有一个临时文件,但编译器可以自行决定是否删除该临时文件。