12

我有一堂很长的课,里面有很多数据成员。我想为它写一个复制构造函数。但是,如果我编写自己的复制构造函数,我将无法访问默认的复制构造函数。

我只想在我自己的复制构造函数中修复一些指针。所以我想要一个对象的浅拷贝,这可以通过默认的拷贝构造函数来完成。

当我有自己的复制构造函数时,是否有可能访问默认的复制构造函数?

4

8 回答 8

13

将您不想更改的内容包装在结构中,并从中(私下)派生。在您的复制构造函数中,只需调用基类的复制构造函数。

于 2012-09-14T10:57:32.287 回答
8

不,您不能同时拥有默认和自己的副本 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;
};

我总是选择第一个解决方案。

[更新]

还有第三种解决方案,与我的第二种解决方案非常相似,将您的琐碎部分包含在私有继承的基类中。我仍然更喜欢第一种解决方案。

于 2012-09-14T10:57:35.237 回答
4

最简单的方法是将指针包装到将在其复制构造函数中手动执行“修复”的类中,然后您可以愉快地使用默认的复制构造函数。

于 2012-09-14T10:58:58.813 回答
0

不,没有办法从用户定义的复制构造函数中调用默认的复制构造函数。

于 2012-09-14T10:56:01.617 回答
0

我的解决方案是一个简单的 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;  
}
于 2014-10-20T08:06:29.427 回答
0

您可以使用默认值或您自己的,不能同时使用两者。如果您想为不同的对象选择不同的功能,您应该只编写一个处理这种情况的成员函数。

void DeepCopy(MyClass* rhs);

例如。

于 2012-09-14T11:00:02.410 回答
0

如果您创建了自己的,则无法访问默认复制 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;
  }

};
于 2012-09-14T11:09:36.063 回答
0

这对我有用......(C ++ 11,不知道它是否适用于旧标准)不知道为什么它不会进入无限循环。

class Foo {
public:
  Foo(const Foo &orig) {
     *this = orig;
     ... exchange pointers, do own stuff
  }
于 2016-11-09T09:39:36.263 回答