對於一個示範的緣故想象,我有一些動物類,每一類由「動物」類派生的,每個「知道」,他們是什麼類型的,並且每個具有某種獨特的能力:在C++接口中聲明模板函數?
enum class animal_type { antelope, bear, cat };
class animal
{
};
class antelope : public animal
{
public:
static const animal_type type = animal_type::antelope;
void run() { std::cout << "antelope runs\n"; };
};
class bear : public animal
{
public:
static const animal_type type = animal_type::bear;
void roar() { std::cout << "bear roars\n"; };
};
class cat : public animal
{
public:
static const animal_type type = animal_type::cat;
void meow() { std::cout << "cat meows\n"; };
};
現在,我想根據自己的類型,能夠檢索動物:
class animal_getter
{
public:
animal& get(animal_type t)
{
static antelope s_antelope;
static bear s_bear;
static cat s_cat;
switch (t)
{
case animal_type::antelope:
return s_antelope;
case animal_type::bear:
return s_bear;
case animal_type::cat:
return s_cat;
}
}
};
最後,這將是很好得到的實際類型動物的背部,使調用語法更好:
template<typename T>
T& get()
{
return static_cast<T&>(get(T::type));
}
現在
我可以寫這樣的事:
animal_getter ag;
ag.get<antelope>().run();
而非wordier:
animal_getter ag;
static_cast<antelope&>(ag.get(animal_type::antelope)).run();
我希望沒有什麼太不合理有關。但是現在我想能夠單元測試獲取動物,所以理想情況下可以僞造animal_getter類(假設實際的實現訪問數據庫或者單元測試中不需要的東西,因此是假的) 。所以最好定義一個「動物吸氣」類的接口,然後創建一個實現該接口的假。這裏的問題,可以寫這個接口?這是不會編譯:
struct IAnimalGetter
{
virtual template<typename T> T& get() = 0;
};
是否有可能挽救這個想法或者模板函數永遠不會被宣佈爲虛擬定義,包括用戶的界面的目的是什麼?
如果這個想法不是首發,那麼在什麼時候開始出問題了?當模板函數被寫入了它自己的模型嗎?我是否應該停止返回一個動物對象,然後讓調用者對演員負責?
這是不是很清楚你爲什麼需要這個。公開你的靜態數據成員。 'ag.get().run()'什麼也不做'ag.s_antelope()。run()'不。 –
(續)沒有虛擬模板,所以虛擬'get template'是不可能的。你可以通過訪問者模式和/或ctrategicalky放置演員來解決這個問題,但是你仍然不清楚你想要達到什麼目的。什麼'得到()'買你'get_antelope()'不? –
如果派生類沒有任何共同點,那麼也許錯誤是有一個空的基類?需要投射或打開類型都是模型出現問題的跡象。肯定羚羊不沉默,熊可以跑。 –