【问题标题】:C++ Unexpected behaviour of polymorphic cloningC ++多态克隆的意外行为
【发布时间】:2015-12-03 03:58:24
【问题描述】:

我有一个基类 Animal 和模板派生类 Specie<T>。当我有一个指向基类 Animal 的指针时,我想使用多态克隆来返回正确派生类型的对象。我实现的克隆似乎总是返回一个指向 Animal 的指针。不是我所期望的,但我不明白为什么。另一方面,如果我“手动”执行 dynamic_cast,它会起作用。有什么想法吗?

#include <iostream>


class Dog;
class Cat;
class Rat;


// Base class
class Animal{

public:
  virtual Animal * clone() = 0;

};





// Derived class
template <class T1>
class Specie: public Animal{


public:

  Specie<T1> * clone();

  void DoSomething();


};



// Purpose of clone(): Return a pointer of type Specie<T1> when applied
// to a pointer to class Animal
template <class T1>
Specie<T1> * Specie<T1>::clone(){

  Specie<T1> *obj;

  obj = dynamic_cast<Specie<T1> *>(this);

  return obj;

}






// To identify a Dog
template <>
void Specie<Dog>::DoSomething(){

  std::cout << "This is a Dog..." << std::endl;

}


// To identify a Cat
template <>
void Specie<Cat>::DoSomething(){

  std::cout << "This is a Cat..." << std::endl;

}


int main(){

Specie<Dog> Dingo;
Specie<Cat> Tom;

Dingo.DoSomething();
Tom.DoSomething();


Animal *animal3;
animal3 = &Dingo;






// The following works
// Successfull conversion from pointer-to-Animal to pointer-to-Specie<Cat> with dynamic_cast without using clone()
Animal *animal4 = new Specie<Cat>;
Specie<Cat> *animal5;

// Here I can convert the pointer to Animal to a pointer to Specie<T>
// using dynamic_cast. If animal5 was not of the correct type, the compiler would return an error.
animal5 = dynamic_cast<Specie<Cat>*>(animal4);
animal5->DoSomething(); // result ok



// I want to do the same in an automated manner with clone()
// The following DOES NOT WORK with clone()
// clone() does not return a pointer to Specie<T> as expected
// but a pointer to Animal. The compiler complains.
Animal *animal6 = new Specie<Dog>;
Specie<Dog> *bobby;
bobby = animal6->clone();


return 0;
}

错误:“Animal *”类型的值不能分配给“Specie *”类型的实体 bobby = animal6->clone();

为什么它在 main 中使用 dynamic_cast 但不使用 clone() ? 提前致谢。

【问题讨论】:

  • 顺便说一句,您的 Clone 只是返回 this 而不是 *this 的副本。

标签: c++ polymorphism clone


【解决方案1】:

没有dynamic_cast 就无法工作,因为Animal::clone静态 返回类型是Animal*animal6动态 类型是Specie&lt;Dog&gt;,但这并没有进入在编译时为返回clone 函数而推断的类型。

如果你真的需要这个,dynamic_cast 是必要的,但这是代码异味。如果您发现自己非常需要对象的绝对动态类型,而不仅仅是使用虚函数,那么您应该考虑重新设计。

【讨论】:

  • 谢谢。我在函数 clone() 中使用了 dynamic_cast,但它似乎没有帮助。
  • @ChristopheJ.Ortiz 不会更改 clone 函数的静态类型。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2023-04-09
  • 2018-01-15
  • 1970-01-01
  • 2011-10-14
  • 1970-01-01
  • 2011-03-29
  • 2018-08-28
相关资源
最近更新 更多