[英]C++ inheritance in template parameter
我需要將模板作為函數參數傳遞,但模板必須接受所有繼承的對象。
例如:
template <class T>
class Template {
public:
Template() {}
};
// IMPORTANT: must accept all children of "Base"
class Test {
Template<Base> *pointer;
public:
Test(Template<Base> *pointer) {...}
};
main() {
Template<Base> *base = new Template<Base>();
Template<Child1> *child = new Template<Child1>();
Test *test1 = new Test(base); // WORKING
// NEXT LINE IS IMPORTANT:
Test *test2 = new Test(child); // ERROR: no matching function for call to 'Test::Test(Template<Child1>*&)'
}
class Base {...};
class Child1 : public Base {...};
class Child2 : public Base {...};
..
我需要最有效的方法,如何在“Test”類中存儲模板,這將接受所有子類。 我有很多兒童班。
1)是否可以在參數中為Child類進行一些向上轉換(static_cast)? 在“模板”里面或“測試”類里面使用它會很好。 不是,在創建新的“Test”對象時,因為會有很多新對象。
2)或者傳遞沒有模板參數的參數Test(Template *pointer) {...}
?
或者如何解決?
您想要做的事情不起作用的原因是因為模板類型不遵守typename參數中的繼承。
Template<Base> *base
和
Template<Child1> *child
是完全不同的類型。 嘗試使用一個代替另一個就像嘗試將int
傳遞給具有string
參數的函數。
也就是說,我相信你有兩個可行的選擇。
Test
成為模板 一種選擇是將Test
作為模板:
template <typename T>
class Test {
T *pointer;
public:
Test(T *pointer) {...}
};
這將允許Test
對象使用傳遞給它的任何對象。
或者,通過創建接口並在Template
實現該接口,您可以將接口傳遞給Test
類:
/**
* Interface that declares the virtual methods that
* will be used by your Test class.
*/
class ITemplate {
public:
virtual ~ITemplate() {}
// Define your methods here.
virtual void Foo() = 0;
virtual void Bar() = 0;
virtual void Baz() = 0;
}
/**
* Concrete ITemplate implementation.
*/
template <class T>
class Template : public ITemplate {
public:
Template() {}
virtual ~Template() {}
virtual void Foo() override {}
virtual void Bar() override {}
virtual void Baz() override {}
};
class Test {
ITemplate *pointer;
public:
Test(ITemplate *pointer) {...}
};
這樣做的好處是,您可以在不影響Test
類的情況下修改Template
類,因為Test
類可以使用ITemplate
接口而不是具體對象。 這樣做的缺點是會產生虛函數查找的成本,如果您嘗試編寫極其高效的代碼,這可能是不可取的。
1)是否可以在參數中為Child類進行一些向上轉換(static_cast)? 在“模板”里面或“測試”類里面使用它會很好。 不是,在創建新的“Test”對象時,因為會有很多新對象。
我不完全明白你的建議。 不可能將不相關的指針強制轉換為另一個指針。
2)或者不帶模板參數傳遞參數
不可以。模板不能是函數參數。
您可以做的是使Template<T>
隱式轉換為Template
其他實例:
template <class T>
class Template {
public:
// ...
template<class U>
Template(const Template<U>&);
};
根據轉換構造函數的實現方式,它可能會對U
施加限制。
而且,如果您要在Test
存儲Template<Base>
實例而不是指針:
class Test {
Template<Base> member;
// ...
};
然后,您可以接受Template<Base>
按值(復制)或通過rvalue-reference(移動)到構造函數。 Template<Child>
將隱式轉換為Template<Base>
:
class Test {
Template<Base> member;
public:
Test(Template<Base> argument) {/* ... */}
};
此方法與用於允許隱式向上轉換標准智能指針類型的方法相同。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.