为什么析构函数和复制构造函数使用对象数组显示此行为

Why destructor and copy constructor is showing this behavior with array of objects?

本文关键字:显示 数组 对象 析构函数 复制 构造函数 为什么      更新时间:2023-10-16

当数组使用匿名对象初始化时,析构函数显示有效值,但我创建一个包含对象的数组,覆盖复制构造函数不调用,析构函数也显示垃圾值。

我试图通过显示值来理解这一点,但仍然感到困惑。

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 CONSTRUCTORn";
        }
        ~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 次,但只有两次,没有垃圾值。实际输出如下所示:

COPY CONSTRUCTOR 
COPY CONSTRUCTOR 
32649 DESTRUCTOR  
-1330935392 DESTRUCTOR  
3 DESTRUCTOR  
2 DESTRUCTOR  
4 DESTRUCTOR  
5 DESTRUCTOR

原因是因为复制省略。

在这种情况下:

Check b[2] = {Check(5),Check(4)};

由于这两个值都是临时值,因此允许编译器(或者在 C++17 中强制(优化副本,而是就地构造对象。

但是,在第二种情况下:

Check a[2] = {obj1,obj2};

obj1obj2不是临时的,因此在这种情况下必须出现真实副本。

在:

Check b[2] = {Check(5),Check(4)};

此语法意味着两个数组元素的构造函数参数是 54 。 这并不意味着这些论点是暂时的。

Check(5)是一个 prvalue 表达式,但这并不一定意味着暂时的实现。可以"使用"prvalue 的方法之一是作为相同类型的对象的初始值设定项。

这种行为在 C++17 中发生了变化;在此之前,概念上总是有一个临时的,但编译器可以自行决定省略临时的。