使用复制构造函数后,双重释放子对象

eKK*_*KiM 4 c++ constructor destructor copy-constructor

我无法弄清楚为什么(似乎)一个物体被毁坏了两次.

如果我创建一个类(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;
}
Run Code Online (Sandbox Code Playgroud)

这会产生以下输出:

class A default Constructor - object id: 1
class A default Constructor - object id: 2
class A copy constructor - object id: 3
class A destructor - object id: 3
class A destructor - object id: 3
class A destructor - object id: 1
Run Code Online (Sandbox Code Playgroud)

对象id 3被破坏两次,而对象id 2根本没有被破坏.

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

如果你投票.请说明原因.我很乐意尝试改进我的问题.

Yak*_*ont 5

你需要遵循5规则.如果你实现了一个非平凡的析构函数,复制/移动赋值/构造,你必须实现全部5,或者给出一个很好的理由,或者删除它们.

你实现了destory和copy ctor.你忽略了其他3.添加它们.

更重要的是characters = A<char>(b2.characters);你的拷贝构造函数调用拷贝赋值.您没有跟踪哪个,这就是您的计数关闭的原因.你指定柜台.