c++ - 对复制构造函数和析构函数的无关调用

标签 c++ destructor copy-constructor

[跟进 this question ]

class A
{
    public:
         A()          {cout<<"A Construction"     <<endl;}
         A(A const& a){cout<<"A Copy Construction"<<endl;}
        ~A()          {cout<<"A Destruction"      <<endl;}
};

int main() {
    {
        vector<A> t;
        t.push_back(A());
        t.push_back(A());   // once more
    }
}

输出是:

A Construction        // 1
A Copy Construction   // 1
A Destruction         // 1
A Construction        // 2
A Copy Construction   // 2
A Copy Construction   // WHY THIS?
A Destruction         // 2
A Destruction         // deleting element from t
A Destruction         // deleting element from t
A Destruction         // WHY THIS?

最佳答案

为了清楚地看到发生了什么,我建议在输出中包含 this 指针以识别哪个 A 正在调用该方法。

     A()          {cout<<"A (" << this << ") Construction"     <<endl;}
     A(A const& a){cout<<"A (" << &a << "->" << this << ") Copy Construction"<<endl;}
    ~A()          {cout<<"A (" << this << ") Destruction"      <<endl;}

我得到的输出是

A (0xbffff8cf) Construction
A (0xbffff8cf->0x100160) Copy Construction
A (0xbffff8cf) Destruction
A (0xbffff8ce) Construction
A (0x100160->0x100170) Copy Construction
A (0xbffff8ce->0x100171) Copy Construction
A (0x100160) Destruction
A (0xbffff8ce) Destruction
A (0x100170) Destruction
A (0x100171) Destruction

所以流程可以解释为:

  1. 创建了临时 A (...cf)。
  2. 临时 A (…cf) 被复制到 vector (…60) 中。
  3. 临时A(…cf)被销毁。
  4. 创建了另一个临时 A (...ce)。
  5. vector被展开,那个vector中的旧A(…60)被复制到新的地方(…70)
  6. 将另一个临时 A (…ce) 复制到 vector (…71) 中。
  7. A (…60, …ce) 的所有不必要的拷贝现在都被销毁了。
  8. vector 被破坏,所以里面的A(…70, …71)也被破坏。

如果你这样做,第 5 步将消失

    vector<A> t;
    t.reserve(2); // <-- reserve space for 2 items.
    t.push_back(A());
    t.push_back(A());

输出将变为:

A (0xbffff8cf) Construction
A (0xbffff8cf->0x100160) Copy Construction
A (0xbffff8cf) Destruction
A (0xbffff8ce) Construction
A (0xbffff8ce->0x100161) Copy Construction
A (0xbffff8ce) Destruction
A (0x100160) Destruction
A (0x100161) Destruction

关于c++ - 对复制构造函数和析构函数的无关调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2657752/

相关文章:

c++ - 在具有某些约束(内括号)正则表达式的句子中的括号之间查找单词

c++ - 增长数组 C++ 的最有效方法

c++ - gltf 没有在皮肤中指定骨架值是什么意思?

c++ - 如何手动销毁成员变量?

c++ - vector 派生类的复制构造函数

c++ - 通过复制将 opengl 对象包装到 C++ 类中

c++ - 有没有快速创建集合的方法?

c# - 在析构函数中执行新进程

c# - ILSpy 中显示的奇怪的类成员语法

class - 具有成员 std::mutex(或其他不可复制对象)的类的复制或移动构造函数?