我有一堂很长的课,里面有很多数据成员。我想为它写一个复制构造函数。但是,如果我编写自己的复制构造函数,我将无法访问默认的复制构造函数。
我只想在我自己的复制构造函数中修复一些指针。所以我想要一个对象的浅拷贝,这可以通过默认的拷贝构造函数来完成。
当我有自己的复制构造函数时,是否有可能访问默认的复制构造函数?
我有一堂很长的课,里面有很多数据成员。我想为它写一个复制构造函数。但是,如果我编写自己的复制构造函数,我将无法访问默认的复制构造函数。
我只想在我自己的复制构造函数中修复一些指针。所以我想要一个对象的浅拷贝,这可以通过默认的拷贝构造函数来完成。
当我有自己的复制构造函数时,是否有可能访问默认的复制构造函数?
将您不想更改的内容包装在结构中,并从中(私下)派生。在您的复制构造函数中,只需调用基类的复制构造函数。
不,您不能同时拥有默认和自己的副本 c-tor。
但是这个问题有两种解决方法:
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;
};
我总是选择第一个解决方案。
[更新]
还有第三种解决方案,与我的第二种解决方案非常相似,将您的琐碎部分包含在私有继承的基类中。我仍然更喜欢第一种解决方案。
最简单的方法是将指针包装到将在其复制构造函数中手动执行“修复”的类中,然后您可以愉快地使用默认的复制构造函数。
不,没有办法从用户定义的复制构造函数中调用默认的复制构造函数。
我的解决方案是一个简单的 memcpy() 而不是对隐式(编译器生成)复制构造函数的不可能调用,如下所示:
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;
}
您可以使用默认值或您自己的,不能同时使用两者。如果您想为不同的对象选择不同的功能,您应该只编写一个处理这种情况的成员函数。
void DeepCopy(MyClass* rhs);
例如。
如果您创建了自己的,则无法访问默认复制 ctor - 编译器只是不会生成它。但是有一种解决方法 - 将您的类拆分为数据结构和逻辑。
参见示例:
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;
}
};
这对我有用......(C ++ 11,不知道它是否适用于旧标准)不知道为什么它不会进入无限循环。
class Foo {
public:
Foo(const Foo &orig) {
*this = orig;
... exchange pointers, do own stuff
}