在复制构造函数中复制任何指针成员变量
Making copy of any pointer member varible in copy constructor
我有一个类B,它有一个成员是指向a类对象的指针。在类型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类型对象上使用复制构造函数时,复制该对象,但不复制成员变量。
你的代码从未在类a中调用任何复制构造函数。
你的代码调用类B中的复制构造函数,它做的正是应该做的,即复制attribute
的值,这是一个指针到类a对象。
换句话说,在执行代码之后,你有两个类B实例和一个类A实例。在两个B类实例中,attribute
指向同一个A类实例。
这(很可能)不是你想要的。
正如许多人已经指出的那样(例如,参见@lostbard answer),您需要在类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 ©)
{
// 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指出的,当你创建复制构造函数时,你应该总是实现一个赋值操作符(三规则),所以我把它添加到上面的代码中。
有些人把"三规则"当作"五规则",所以它也包括"移动"。阅读更多:https://en.wikipedia.org/wiki/Rule_of_three_(C%2B%2B_programming)
虽然有许多解决方案,但我敢打赌您迟早会实现通常的虚拟a.clone();
。当您有A的派生类时,这种方法可以完美地工作(这或多或少是您将A保留为指向堆分配对象的指针而不是值成员的唯一合法原因:))。
注意,当您在层次结构中实现clone()
时,c++支持协变指针返回类型。因此,如果base有一个返回Clonable*
的虚函数,那么A
的相同方法可以返回A*
,而a的后代ADerived
可以返回ADerived*
。对于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 ©)
{
attribute = new A(*copy.attribute);
}
~B()
{}
};
- 是否可以初始化不可复制类型的成员变量(或基类)
- 为什么类中的ostringstream类型的成员会导致";调用隐含删除复制构造函数";错误
- 访问类成员而不复制此变量或互斥变量
- std::ofstream 作为类成员删除复制构造函数?
- 正在复制具有未初始化成员的结构
- 直接初始化不可复制、不可移动的成员,而不使用聚合初始化
- 具有 STL 向量类型成员的类的复制内存
- 是否可以将不可复制的成员用作使对象不可复制的替代方法?
- 将C++浮点数组成员直接封送到 C#,而无需复制
- 在临时将成员带出时省略复制/移动
- 复制赋值函数如何访问另一个对象的私有成员(Stroustroup 原则和实践书)?
- C++ 阻止复制成员数据
- C++列表:复制成员列表中的本地列表
- 使用模板类复制成员函数
- 即使复制构造函数由于 RVO 在C++中未被调用,如何复制成员变量的值
- 具有不可复制成员的类的聚合初始化
- 请参阅 TC++PL 第 3 版的第 10.4.6.3 节"复制成员"
- 初始化不可复制成员
- 关于包含不可复制成员引用的类的复制构造函数的建议
- 错误到底是什么,对于错误地调用可移动和不可复制成员的复制构造函数有什么解决方法