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

时间:2016-06-23 19:23:40

标签: c++ copy-constructor

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

"f" == "F" (should be treated the same)

3 个答案:

答案 0 :(得分:1)

  

在类型A的对象上使用复制构造函数时,会复制它,但成员变量不是。

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

您的代码在B类中调用复制构造函数,它完全按照预期的方式执行,即将attribute的值(指针)复制到A类对象。

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

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

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

此外,您应该在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;
}

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

修改

正如@Slava所指出的那样,当你创建一个复制构造函数(规则为3)时,你应该总是实现一个赋值运算符,所以我把它添加到上面的代码中。

有些人喜欢三个规则,因此它也包括移动。在此处阅读更多内容:https://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)

答案 1 :(得分:0)

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

请注意,当您在层次结构中实现clone()时,该C ++支持协变指针返回类型。因此,如果base具有返回的虚拟例如Clonable*,然后A相同的方法可以返回A*,而A的后代ADerived可以返回ADerived*。随意了解&#39; can&#39;作为&#39;应该&#39;对于clone()的情况。

答案 2 :(得分:0)

为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()
    {}
};