我有一个数据成员很多的长类。我想为它编写一个复制构造函数。但是,如果我编写了自己的复制构造函数,我将失去对默认复制构造函数的访问。
我只想在我的复制构造函数中修复几个指针。因此,我想要对象的浅拷贝,这可以通过默认的复制构造函数完成。
当我有自己的复制构造函数时,有可能访问默认的复制构造函数吗?
我有一个数据成员很多的长类。我想为它编写一个复制构造函数。但是,如果我编写了自己的复制构造函数,我将失去对默认复制构造函数的访问。
我只想在我的复制构造函数中修复几个指针。因此,我想要对象的浅拷贝,这可以通过默认的复制构造函数完成。
当我有自己的复制构造函数时,有可能访问默认的复制构造函数吗?
将您不想更改的内容包装在一个struct中,并从其派生(私有)。 在您的复制构造函数中,只需调用基类的复制构造函数。
不,你不能同时拥有默认的和自己的复制构造函数。
但是有两种解决这个问题的方法:
1 将指针封装在具有定义复制语义的类中
例如:
class A {
public:
private:
int trivial1;
int trivial2;
...
SomePointer nontrivialMember;
};
class SomePointer {
public:
SomePointer(const SomePointer&); // here the non trivial part of A copy semantics
int* nonTrivialMember;
};
2将琐碎的参数封装在一些琐碎的结构中。
示例:
class A {
public:
A(const A& o) : data(o.data) {
// non trivial part
}
private:
struct Data {
int trivial1;
int trivial2;
...
} data;
int* nontrivialMember;
};
我总是会选择第一种解决方案。
[更新]
还有第三种解决方案,与我的第二种解决方案非常相似,将你的琐碎部分封装在私有继承的基类中。但我仍然更喜欢第一种解决方案。
最简单的方法是将指针封装到类中,并在它们的复制构造函数中手动执行“修复”,然后您可以愉快地使用默认的复制构造函数。
你可以选择默认功能或自定义功能,但不能同时使用两者。如果你想为不同的对象选择不同的功能,你应该编写一个成员函数来处理这种情况。
void DeepCopy(MyClass* rhs);
如果您创建了自己的默认复制构造函数,则无法访问它 - 编译器不会生成它。但是有一个解决方法 - 将类分成数据结构和逻辑。
请参见以下示例:
struct Data
{
int i;
std::string s;
Data(): i(), s() {}
};
class Code: private Data
{
public:
Code() {}
Code(const Code& rhs): Data(rhs) // Call default copy ctor
{
i = 42; // Your copy part
return *this;
}
};
Class Foo
{
public:
...
Foo (Foo & other) {
// copies trivial part (and non-trivial part with possible wrong values)
memcpy(this, &other, sizeof(Foo));
// your non-trivial part here, overwrites the wrong values (if any) above.
}
}
然而,这种副作用是memcpy()也会复制那些非平凡的部分,这是一种浪费。如果非平凡的部分不包含太多空间,我更喜欢我的解决方案。
例如,像下面这样的一个类只浪费了一个指针的4字节复制,假设指针的大小为4字节。
Class Bar
{
int x, y, z;
// memcpy() wastes these 4 bytes copy,
// since actual copy constructor wants a new string
string *s;
}
不,无法从用户定义的复制构造函数中调用默认的复制构造函数。
这对我有用...(C++11,不确定它是否适用于旧的std) 不确定为什么它不会陷入无限循环。
class Foo {
public:
Foo(const Foo &orig) {
*this = orig;
... exchange pointers, do own stuff
}
*this = orig
调用的是复制赋值运算符,而不是复制构造函数。 - bolov