多态性:代码中的复杂性错误.需要一个解释

Polymorphism: Compliation Error in the code.Need an Explanation

本文关键字:解释 一个 代码 错误 复杂性 多态性      更新时间:2023-10-16

下面的代码给出的编译错误如下:第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;
}

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

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

编辑:我为没有直接回答而道歉:

AClass* s2 = dynamic_cast<AClass*>(s1->clone()); 

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

Cloneable* s2 = s1->clone();

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

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