【问题标题】:What's the point of virtual copy constructors (clone functions)?虚拟复制构造函数(克隆函数)有什么意义?
【发布时间】:2013-05-01 13:00:24
【问题描述】:

使用虚拟复制构造函数,类Vehicle 有一个copy() 虚拟成员函数,所有继承的类(如Car)都将实现该函数。

稍后其他一些类可以将任何类型的车辆作为成员变量:

struct Foo {
  Vehicle *v;
  Foo(const Vehicle &veh) {
    v = veh.clone();
  }
};

我不明白这一点。为什么不摆脱clone(),像这样“就地”做new

struct Foo {
  Vehicle *v;
  Foo(Vehicle *veh) {
    v = veh; //veh has no clone()
  }
  ~Foo() {
    delete v;
  }
};

//elsewhere
Foo f(new Car());

有什么缺点(除了它仅适用于“就地”创建)?现在没有人必须实现克隆,一切似乎都变得容易了。

【问题讨论】:

  • 复制指针与复制指针不同。

标签: c++


【解决方案1】:

它们的意义在于,当您有一个 现有 指向基类的指针并想要“无论它是什么”的副本时。

考虑:

class Base;
class Derived1 : public Base;
class Derived2 : public Base;

Derived1* d1 = new Derived1();
Derived2* d2 = new Derived2();
makeACopy(d1);
makeACopy(d2);

void makeACopy(Base* base) {
    // ???  What is it?
};

my answer herehere

【讨论】:

  • 我不明白。 makeACopy 在做什么?
  • @7Cows,它应该是说明性的;)查看其他答案。当我们有一个指向基类的指针并且想要一个具体类的副本无论它可能是什么时,使用克隆。
【解决方案2】:

嗯,在你的例子中,它工作正常。但是如果:

 Foo* MakeCar()
 {
    Car c;
    Foo *f = new Foo(&c); 
 }

或:

 Car *c = new Car;
 Foo f(c);
 delete c;
 ... use f in a way that needs c here. 

通过克隆对象,您不会遇到我刚刚在上面创建的问题。 Foo 对象完全控制着 Car 的生命周期。

编辑:它必须是一个虚函数,这样CarMotorBikeTruck 可以根据它实际是什么对象来做不同的事情。

【讨论】:

  • 如果我们知道可以避免克隆功能: A) 对象是“不可变的”,即在创建后不能被任何人更改。 B)我们使用智能指针(shared_ptr)指向对象?这是个好主意吗?
  • 在我上面展示的任何一种情况下,不变性都无济于事。我认为智能指针不能指向本地对象,它会跟踪对象的生命周期,所以这可能会起作用。据我所知,智能指针总是一个好主意。
【解决方案3】:

因为您的第二个示例不遵循三规则,因此如果曾经复制 Foo(例如,如果您曾经在 std::vector 中使用过 Foo )将会崩溃。

在 C++ 中,大多数情况下您都需要有效的复制构造函数,而 clone 是一个很好的方法。

【讨论】:

    【解决方案4】:

    想象一下:

    Car *c = new Car();
    Foo f1(c);
    Foo f2(c);
    

    ...然后在调用 Foo 析构函数时观看烟花。

    【讨论】:

      猜你喜欢
      • 2013-05-28
      • 1970-01-01
      • 2014-02-12
      • 1970-01-01
      • 1970-01-01
      • 2012-04-13
      • 1970-01-01
      • 1970-01-01
      • 2010-09-09
      相关资源
      最近更新 更多