简体   繁体   English

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

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

When array was initialized with anonymus objects, destructor is displaying valid values, but I create an array with objects, override copy constructor doesn't call and also destructor is displaying garbage values. 当使用匿名对象初始化数组时,析构函数显示有效值,但是我创建了一个包含对象的数组,重写副本构造函数不会调用,析构函数也会显示垃圾值。

I have tried understanding this by displaying values but still confused. 我试图通过显示值来理解这一点,但仍然感到困惑。

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};

I was expecting the "COPY CONSTRUCTOR" output 4 times but it was only two times and no garbage values. 我期待“ COPY CONSTRUCTOR”输出4倍,但它只有2倍,没有垃圾值。 Actual output is shown below: 实际输出如下所示:

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

The reason is because of copy elision. 原因是由于复制省略。

In this case: 在这种情况下:

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

Since both values are temporaries, the compiler is allowed (or, in C++17, forced) to optimize the copy away and instead construct the objects in place. 由于这两个值都是临时值,因此允许编译器(或在C ++ 17中为强制执行)优化副本,然后就地构造对象。

However, in the second case: 但是,在第二种情况下:

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

obj1 and obj2 are not temporaries, so real copies must occur in this case. obj1obj2不是临时的,因此在这种情况下必须出现真实副本。

In: 在:

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

this syntax means that the constructor arguments for the two array elements are 5 and 4 . 此语法意味着两个数组元素的构造函数参数为54 It does not mean that the arguments are temporaries. 这并不意味着参数是临时的。

Check(5) is a prvalue expression , this does not necessarily mean a temporary is materialized. Check(5)是一个prvalue表达式 ,这不一定表示一个临时实例 One of the ways a prvalue can be "consumed" is as the initializer for an object of the same type. 可以使用prvalue的一种方式是将其用作同一类型对象的初始化程序。

This behaviour changed in C++17; 在C ++ 17中,此行为已更改; prior to that, there was conceptually always a temporary but the temporary could be omitted at the compiler's discretion. 在此之前,概念上总是有一个临时文件,但是可以由编译器自行决定是否删除该临时文件。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM