我有一個模板類Specie< T>
派生自基類Animal
。我創建了一個指向Animal的指針矢量,以便將不同類型的對象Specie<T>
存儲在同一個矢量中。 T可以是狗,貓等......C++多態克隆模板類。不能使用克隆的對象作爲參數在功能
現在我想在模板函數中使用vector的某些元素作爲參數。我爲不同的模板參數T編寫了函數的不同特化,因此每個Specie<T>
的行爲都不相同。爲了從矢量中獲得正確類型的每個對象,我使用了多態克隆。它運作良好,我得到正確類型的對象Specie<T>
(請參閱下面的非常簡短的測試)。但是,當我想使用矢量的元素作爲模板函數的參數時,它不起作用。
// 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()));
什麼是錯在我的代碼?提前致謝!
'clone()'的結果仍然是'Animal *'類型,由於返回類型的協變性,它可以在子類中重寫,但在基類中調用成員函數時不起作用 –
除了@PiotrSkotnicki的評論:你沒有'Interaction :: DoSomething'接受一個類型爲'Animal'的對象 –
@SimonKraemer是的,沒錯。我沒有定義Interaction :: DoSomething(Animal),因爲它只對特定的動物(狗,貓,...)有意義。交互隨着每種動物類型而改變。因此我只定義了Interaction :: DoSomething(Specie)。 –