簡體   English   中英

使用CRTP時的對象切片

[英]Object slicing when using CRTP

使用CRTP時,我遇到了對象切片問題。 以下模擬說明了我的問題。

#include <memory>

class CrtpGenr
{
};

template<class t_object>
class CrtpBase : public CrtpGenr
{
    public:
        static
        auto create() -> std::unique_ptr<t_object> {
            return(std::unique_ptr<t_object>(new t_object));
        }
        void funct1(){}
};

class CrtpDirv1 : public CrtpBase<CrtpDirv1>
{
    public:
        void funct2(){}
};

class CrtpDirv2 : public CrtpBase<CrtpDirv2>
{
    public:
        void funct2(){}
};


int main()
{
/*
    // This works
    std::unique_ptr<CrtpDirv1> crtp_obj = CrtpDirv1::create();
    crtp_obj->funct1();
    crtp_obj->funct2();
*/

    std::unique_ptr<CrtpGenr> crtp_obj1 = static_cast<std::unique_ptr<CrtpGenr>>(CrtpDirv1::create());
    std::unique_ptr<CrtpGenr> crtp_obj2 = static_cast<std::unique_ptr<CrtpGenr>>(CrtpDirv2::create());
    crtp_obj1->funct1();
    crtp_obj1->funct2();

    return 0;
}

編譯上面的代碼會給我以下錯誤:

main.cpp: In function 'int main()':
main.cpp:47:16: error: 'class CrtpGenr' has no member named 'funct1'
 crtp_obj1->funct1();
            ^
main.cpp:48:16: error: 'class CrtpGenr' has no member named 'funct2'
 crtp_obj1->funct2();

我希望能夠將CrtpDirv1和CrtpDirv2類轉換為CrtpGenr。 這樣可以定義一個CrtpGenr類型的容器來容納CrtpDirv1或CrtpDirv2的對象。 我究竟做錯了什么?

*crtp_obj1的類型為CrtpGenr如您在第48行中所聲稱的。事實上,這是正確的,因為整個shebang都源自CrtpGenr 因此static_casts會編譯。

但是,您將繼承問題倒向了,methinks。 看一下CrtpGenr的定義:

class CrtpGenr
{
};

它沒有方法。 您為什么希望編譯器允許您嘗試在該對象上調用一個?

如果進行強制轉換,以便可以將某種常見基本類型的對象放入容器中(例如,“ std :: list”),則可以執行此操作,但是當您要對該對象調用特定方法時,您需要通過將該指針轉換回您創建的類型,可以告訴編譯器它實際上是什么樣的對象。

您可能需要更深入地研究繼承和多態性。 例如,也許CrtpGenr類可以具有派生類實現的虛擬方法funct1()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

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