簡體   English   中英

模板參數中的C ++繼承

[英]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參數的函數。

也就是說,我相信你有兩個可行的選擇。

#1使Test成為模板

一種選擇是將Test作為模板:

template <typename T>
class Test {
    T *pointer;
public:
    Test(T *pointer) {...}
};

這將允許Test對象使用傳遞給它的任何對象。

#2使用界面

或者,通過創建接口並在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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM