簡體   English   中英

為什么我可以使用CRTP將基類的this指針轉換為子類的指針?

[英]Why am I able to cast the this pointer of a base class to a pointer to a child class using the CRTP?

請考慮以下類,這些類采用了好奇重復模板模式(CRTP):

template <typename T>
class Base
{
public:
    virtual ~Base() {}

    void typeOfThis()
    {
        cout << "Type of this:  " << typeid(this).name() << '\n';
        cout << "Type of *this: " << typeid(*this).name() << '\n';
    }

    void callFuncOfTemplateParam()
    {
        static_cast<T*>(this)->hello();
    }
};

class Derived : public Base<Derived>
{
public:
    void hello()
    {
        cout << "Hello from Derived!" << '\n';
    }
};

當我執行以下命令時:

Base<Derived> * basePtrToDerived = new Derived();
basePtrToDerived->typeOfThis();
basePtrToDerived->callFuncOfTemplateParam();

我獲得了這些結果,這對我來說很有意義:

Type of this:  P4BaseI7DerivedE
Type of *this: 7Derived
Hello from Derived!

顯然,對callFuncOfTemplateParam內部的hello調用成功,因為this指針指向Derived的實例,這就是為什么我能夠將this指針從Base<Derived>*類型轉換為Derived*類型的原因。

現在,由於執行以下命令而引起混亂:

Base<Derived> * basePtrToBase = new Base<Derived>();
basePtrToBase->typeOfThis();
basePtrToBase->callFuncOfTemplateParam();

我得到以下結果:

Type of this:  P4BaseI7DerivedE
Type of *this: 4BaseI7DerivedE
Hello from Derived!

this*this的類型是合理的,但我不了解呼叫hello如何成功的。 this並不指向的實例Derived ,所以為什么我能夠施展的類型, thisBase<Derived>Derived

注意,我還替換了對static_cast<T*>(this)->hello();的調用static_cast<T*>(this)->hello(); 調用dynamic_cast<T*>(this)->hello(); ,但我仍然獲得相同的結果。 我期望dynamic_cast返回nullptr ,但是沒有。

這些結果令我感到非常驚訝。 感謝您為澄清我的疑問提供的幫助!

用於調用演員hello()未定義行為的時候T不符合真正的類型,對象的this指向。 但是, hello()不訪問任何通過this ,所以它並沒有真正的問題是什么this實際上指向。 您可以輕松地執行reinterpret_cast<T*>(12345)->hello() ,它仍然可以“正常工作”。 但是,您決定強制執行this不會有任何區別,因為hello()只會忽略結果(對於dynamic_cast ,請參見在不訪問任何數據的NULL指針上調用方法會失敗嗎? )。

更改您的類以引入hello()試圖通過this訪問的數據成員,您將看到非常不同的結果(即,代碼可能會崩潰或報告垃圾等)。

暫無
暫無

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

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