在复制构造函数中复制任何指针成员变量

Making copy of any pointer member varible in copy constructor

我有一个 class B,它有一个成员是指向 A class 的对象的指针。在 A 类型的对象上使用复制构造函数时,它被复制但成员变量没有。 有没有办法复制 A 对象并自动复制其 B 成员? 以下代码显示了我正在尝试解释的问题:

class A
{
public:
    A(char t_name)
    {
        name = t_name;
    }
    ~A()
    {
    }
    char name;
};

class B
{
public:
    A* attribute;

    B()
    {
        attribute = new A('1');
    }
    ~B()
    {}
};


int main()
{
    B* b_variable = new B;
    B* b_copy = new B(*b_variable);
    return 0;
}

虽然有很多解决方案,但我敢打赌您迟早会最终实施通常的虚拟 a.clone();。当您导出 A 的 类 时,这将完美无缺(这或多或少是您将 A 保留为指向堆分配对象的指针而不是值成员的唯一合理原因: )).

请注意,当您在层次结构中实现 clone() 时,C++ 支持协变指针 return 类型。因此,如果 base 有一个虚拟的 returns 例如Clonable*,那么A同样的方法可以returnA*和A的后代ADerived可以returnADerived*。对于 clone().

的情况,请随意将 'can' 理解为 'should'

为 A 和 B 创建复制构造函数:

class A
{
public:
    A(char t_name)
    {   
    name = t_name;
    }
    A(const A& copy)
    {   
        name = copy.name;
    }
    ~A()
    {
    }
    char name;
};

class B
{
public:
    A* attribute;

    B()
    {
        attribute = new A('1');
    }
    B(const B &copy)
    {
      attribute = new A(*copy.attribute);
    }
    ~B()
    {}
};

When using copy constructor on an object of type A, it is copied but the member variable is not.

您的代码从不调用 class A 中的任何复制构造函数。

您的代码在 class B 中调用了一个复制构造函数,它完全按照预期执行,即复制 attribute 的值,它是一个 指针 到 class 一个对象。

换句话说 - 执行代码后,您有两个 class B 实例和一个 class A 实例。在两个class B实例中attribute指向同一个class A实例。

这(很可能)不是您想要的。

正如许多人已经指出的那样(例如,参见@lostbard 的回答),您将需要 class B 中的复制构造函数来执行深层复制。需要深拷贝,因为 class B 有一个指针成员。

你还应该在 class B 析构函数和 main.

中做一些清理工作
#include <iostream>
using namespace std;

class A
{
public:
    A(char t_name)
    {
        name = t_name;
    }

    ~A()
    {
    }
    char name;
};

class B
{
public:
    A* attribute;

    B()
    {
        attribute = new A('1');
    }

    /** Copy constructor */
    B(const B &copy)
    {
        // Make a new instance of class A
        attribute = new A(*copy.attribute);
    }

    /** Assignment operator */
    B& operator= (const B& other)
    {
        // Delete the existing class A instance
        delete attribute;
        // and create a new as a copy of other.attribute
        attribute = new A(*other.attribute);
    }

    ~B()
    {
        // Delete the class A instance
        delete attribute;
    }
};


int main()
{
    B* b_variable = new B;
    B* b_copy = new B(*b_variable);

    // Delete the two class B instances
    delete b_variable;
    delete b_copy;

    return 0;
}

class A 中不需要复制构造函数。默认生成的将作为 Class A 没有指针成员。

编辑

正如@Slava 所指出的,当你制作复制构造函数(三规则)时,你应该始终实现一个赋值运算符,所以我将它添加到上面的代码中。

有些人喜欢三的规则是五的规则所以它也包括移动。在这里阅读更多:https://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)