1

以下代码在第 1 行给出编译错误:“无法从 'Cloneable*' 转换为 'AClass*'”。据我所知,它涉及编译时和运行时多态性的概念。但我没有对此的具体推理。请帮助。

struct Cloneable
{
 virtual Cloneable* clone()
  {
  cout << "Cloneable";
  return new Cloneable;
  }

  virtual ~Cloneable() {}
};


struct AClass : public Cloneable
{
  virtual AClass* clone()
  {
  cout << "AClass";
  return new AClass;
  }
};

int main()
{ 
 Cloneable* s1 = new AClass;
 AClass* s2 = s1->clone();      //Line 1
return 0;
}
4

3 回答 3

1

您正在调用clone()指针Cloneable。这个方法返回一个Cloneable*,所以你需要这个:

Cloneable* s2 = s1->clone();

这将实例化一个AClass. 这是使用这个克隆习语的标准方法。如果您正确使用多态性,那么您是否拥有 aCloneable*AClass*. 因此,您通常也会Cloneable*从那里返回AClass::clone()。当然,您最好返回一个智能指针。

struct AClass
{
  virtual std::unique_ptr<Cloneable> clone();
};

struct AClass : public Cloneable
{
  virtual std::unique_ptr<Cloneable> clone();
};
于 2013-02-27T19:27:34.187 回答
1

虽然可以让它与演员一起“工作”,但你正在做的事情是非常危险的。您忘记删除两个动态分配的对象。像这样“隐藏动态内存分配”也不是一个好主意,尤其是不要在任何地方删除它。使用 std::unique_ptr 或 std::shared_ptr 或者只是在堆栈上分配对象会容易得多。

编辑:我很抱歉没有先给出直接的答案:

AClass* s2 = dynamic_cast<AClass*>(s1->clone()); 
于 2013-02-27T19:22:33.683 回答
1

基本上,当您将新的 AClass* 存储在基类指针中时,调用 clone 的结果将是一个 Cloneable*,它需要向下转换为 AClass*,这可能并不总是安全的。因此编译器会想要一个dynamic_cast ()

于 2013-02-27T19:15:26.420 回答