使用模板化类的 C++ 多态克隆。不能将克隆的对象用作函数中的参数

标签 c++ templates arguments polymorphism clone

我有一个模板类 Specie< T>派生自基类 Animal .我创建了一个指向 Animal 的指针 vector 以存储不同类型的对象 Specie<T>在同一个 vector 中。 T 可以是狗、猫等...

现在我想使用 vector 的一些元素作为模板函数中的参数。我为不同的模板参数 T 编写了不同的函数特化,因此每个 Specie<T> 的行为都不同。 .为了从 vector 中获取每个对象的正确类型,我使用了多态克隆。它运行良好,我得到了正确类型的对象 Specie<T> (见下面非常简短的测试)。但是,当我想使用 vector 的一个元素作为模板函数的参数时,它不起作用。

// Base class
class Animal{

 public:
  virtual ~Animal() {}

  virtual Animal *clone() = 0;
  virtual void action() = 0;

};


// Specific types of animals. Forward declaration
class Dog;
class Cat;



// Templated derived class Specie
template <class T>
class Specie : public Animal{

public:
    Specie<T> *clone();

    void action();

};





template <class T>
Specie<T> * Specie<T>::clone() {

   std::cout << "Cloning a Specie<T>" << std::endl;
   return new Specie<T>(*this);

}



// Specialization of templated function action() for Dog
template <>
void Specie<Dog>::action(){

  std::cout << "Wouaf !" << std::endl;

}


// Specialization of templated function action() for Cat
template <>
void Specie<Cat>::action(){

  std::cout << "Miaouuu !" << std::endl;

}




class Interaction{

public:

  template <class T1>
  static void DoSomething(Specie<T1>);

};



// Specialization of templated function DoSomething() for Dog
template <>
void Interaction::DoSomething(Specie<Dog> obj){

std::cout << "Interact with Dog !" << std::endl;

}


// Specialization of templated function DoSomething() for Cat
template <>
void Interaction::DoSomething(Specie<Cat> obj){

std::cout << "Interact with Cat !" << std::endl;

}




int main(){


 Specie<Cat> HelloKitty;
 Specie<Dog> Bobby;

 Animal *Dingo = new Specie<Dog>();

 Animal *Tom = new Specie<Cat>();

// cloning Dingo
 Animal *UnknownAnimal = Dingo->clone();

// We check the type is correct after cloning
 UnknownAnimal->action();

// We check that DoSomething recognizes correctly the type of objects
// and uses the proper specialization
 Interaction::DoSomething(Bobby);
 Interaction::DoSomething(HelloKitty);




// Vector of pointers to Animals
 std::vector<Animal *> myanimals;

// We add an object of type Specie<Dog> and an object
// of type Specie<Cat> to the vector

 myanimals.push_back(&Bobby);
 myanimals.push_back(&HelloKitty);



 Animal *UnknownAnimal2 = myanimals[1]->clone();

// We check the type is correct after cloning
 UnknownAnimal2->action();



// NOW WE TRY TO USE THE ELEMENT FROM VECTOR AS ARGUMENT OF 
// SPECIALIZED FUNCTION. DOES NOT WORK.
 Interaction::DoSomething(*(myanimals[0]->clone()));



  return 0;
}

error: no instance of function template "Interaction::DoSomething" matches the argument list

argument types are: (Animal) Interaction::DoSomething(*(myanimals[0]->clone()));

我的代码有什么问题?提前致谢!

最佳答案

您正在调用基类函数 virtual Animal *clone() = 0;,它似乎总是返回一个 Animal

函数重载在编译时起作用,不能根据参数的动态类型改变调用。为此,您需要虚函数调用。

关于使用模板化类的 C++ 多态克隆。不能将克隆的对象用作函数中的参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32224335/

相关文章:

c++ - boost smart_ptr非线程安全宏,真的存在吗?

c++ - 我如何修改此函数,以便如果函数的参数是特定结构,它会返回具有更大整数的结构?

c++ - 如何获取 boost::fusion::map 中值的类型?

c++ - C/C++ 宏参数包含点(成员访问运算符)

c++ - OpenGL VBO批处理最佳做法

c++ - 为什么我们在迭代可变模板参数时必须使用额外的构造?

c++ - 无法使用 Armadillo 示例编译 rinside

c++ - 指向实现模式的指针

perl - Perl 中的子例程与脚本

mysql - 从表单提交中提取日期参数时遇到问题