簡體   English   中英

dynamic_cast“this”到派生類型:什么時候合法?

[英]dynamic_cast “this” to derived type: when is it legal?

這是一個顯然不起作用的代碼,因為在構造函數中向下轉換“this”是非法的:

#include <cassert>

class A {
protected:
        virtual ~A() {}
public:
        A();
};

class B : public A {
};

A::A() {
        assert(dynamic_cast<B*>(this));
}

int main(void) {
        B b;
        return 0;
}

正如預期的那樣,當用g ++編譯時,斷言失敗了。

這是另一個代碼,但是,有效(至少使用g ++ 4.7,我還沒有嘗試過其他編譯器):

#include <cassert>

class A {
protected:
        virtual ~A() {}
public:
        A() {}
        void f();
};

class B : public A {
public:
        B() {
                f();
        }
};

void A::f() {
        assert(dynamic_cast<B*>(this));
}

int main(void) {
        B b;
        return 0;
}

我的問題是:第二個代碼是“合法的”,即我可以期望任何編譯器都可以這樣工作嗎?

我的直覺是,因為從B的構造函數的主體調用f(),所以“b”已經很好地形成為類型B的實例,這使得代碼合法。 然而,我仍然有點像構造函數那樣動態播放“this”......

(請注意,我的問題不是這是否是好的做法,只要它是合法的)。

是的,第二個例子定義明確,演員表會成功。 B的構造函數期間,對象的動態類型是B ,因此對B*的強制轉換將成功。

在第一個例子中,如你所說,在A的構造函數中,動態類型是A ,因此對B*的強制轉換將失敗。

我的問題是:第二個代碼是“合法的”

是的,沒關系。

我的直覺是,因為從B的構造函數的主體調用f(),所以“b”已經很好地形成為B類的實例,這使得代碼合法

無論如何它都是合法的,但這就是斷言成功而不是失敗的原因:當你在B的構造函數體內時,你有一個B類實例

然而,我仍然有點像構造函數那樣動態播放“this”......

請注意, A::f在您調用它的任何地方都是靜態良好的形式 - 如果從A::A調用,它將只是動態地使assert失敗。 你也可以實例化一個A並直接在它上面調用f (因為A不是抽象的) - 它仍然是格式良好的,但會使assert失敗。

暫無
暫無

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

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