C++ 使用复制构造函数后释放子对象

C++ 使用复制构造函数后释放子对象,c++,constructor,destructor,copy-constructor,C++,Constructor,Destructor,Copy Constructor,我很难弄清楚为什么一个物体被破坏了两次 如果我创建一个类(B)的对象,其中包含另一个类(a)的对象,然后复制这个对象。复制的对象被销毁两次。虽然看起来像这样。我无法计算出这个输出 我创建了以下(最低?)示例,似乎触发了我的问题: #include <stdio.h> #include <stdint.h> template <class T> class A { public: A() { myCtr = ++ctr;

我很难弄清楚为什么一个物体被破坏了两次

如果我创建一个类(B)的对象,其中包含另一个类(a)的对象,然后复制这个对象。复制的对象被销毁两次。虽然看起来像这样。我无法计算出这个输出

我创建了以下(最低?)示例,似乎触发了我的问题:

#include <stdio.h>
#include <stdint.h>

template <class T>
class A
{
public:
    A()
    {
        myCtr = ++ctr;
        printf("class A default Constructor - object id: %u\n", myCtr);
    }

    A(const A<T> &a2) {
        myCtr = ++ctr;
        printf("class A copy constructor - object id: %u\n", myCtr);

    }

    ~A()
    {
        printf("class A destructor - object id: %u\n", myCtr);
    }

    void add(T item) {
        /* Irrelevant */
    }

private:
    uint64_t myCtr;
    static uint64_t ctr;
};

class B
{
public:
    B() {

    }

    B(char * input, uint32_t len) {
        for (uint32_t i = 0; i < len; i++)
        {
            characters.add(input[i]);
        }
    }

    B(const B &b2) {
        characters = A<char>(b2.characters);
    }

    ~B() {

    }


private:
    A<char> characters;
};

template <class T>
uint64_t A<T>::ctr = 0;

int main(int argc, char *argv[]) {
    B b1 = B((char *)"b1", 2);
    B b2 = B(b1);

    return 0;
}
对象id 3被销毁两次,而对象id 2根本没有销毁

我正在使用以下编译器: Microsoft(R)C/C++优化编译器版本19.14.26429.4

以防你否决投票。请说明原因。我很乐意尝试改进我的问题。

您需要遵循以下步骤。如果您实现了一个非平凡的析构函数copy/move assign/construct,那么您必须实现所有5个,或者给出一个很好的理由,或者删除它们

您实现了destory和copyctor。你忽略了另外三个。添加它们


还有什么
characters=A(b2.characters)您的复制ctor调用复制分配。你没有跟踪,这就是为什么你的计数被取消了。您可以在柜台上进行分配。

混乱来自这一行

characters = A<char>(b2.characters);

注意
characters=A(b2.characters)
是由编译器自动生成的复制赋值。我在我的示例中实现了构造函数?还是我做错了什么?我使用移动分配操作符创建了一个关于我遇到的问题的后续问题:
characters = A<char>(b2.characters);
template <class T>
class A
{
public:
    A()
        : myCtr( ++ctr )
    {
        printf("class A default Constructor - object id: %u\n", myCtr);
    }

    A(const A<T> &a2)
        : myCtr( ++ctr )
    {
        printf("class A copy constructor - object id: %u\n", myCtr);

    }

    A<T>& operator=(const A<T> &a2) {
        // Copy what's needed from a2 here.
        return *this;
    }

    ~A()
    {
        printf("class A destructor - object id: %u\n", myCtr);
    }

    void add(T item) {
        /* Irrelevant */
    }

private:
    const uint64_t myCtr;
    static uint64_t ctr;
};