0

間違って何かばかげたことを書きましたが、驚いたことにうまくいきました。

class A
{    public:
        void print()
        {
            std::cout << "You can't/won't see me !!!" << std::endl;
        }  
        A* get_me_the_current_object()
        {
            return this;
        }
};  
int main()
{
    A* abc = dynamic_cast<A*>(abc);
    abc->print();
}

ここではA* abc = dynamic_cast<A*>(abc)、宣言されていないポインターで dynamic_cast を実行しています。しかし、それは機能するので、上記のステートメントは次のように壊れていると想定しました。

A* abc;
abc = dynamic_cast<A*>(abc);

したがって、それは機能します。ただし、次のようなさらに奇妙なシナリオを試してみると、次のようになります。

A* abc;
abc->print();

そしてさらに

A* abc = abc->get_me_the_current_object(); 
abc->print();

これらの例がどのように機能し、マッピングが行われたかを見て、私はびっくりしました。
誰かがこれらがどのように機能しているのか詳しく説明してもらえますか? 前もって感謝します。

4

2 に答える 2

6

未定義の動作や C++ のバグがあるからといって、劇的なクラッシュやコンピューターの発火が予想されると考えるのはよくある間違いです。何も起こらないこともあります。これは、コードが「機能する」という意味ではありません。まだバグがあるためです。症状が現れていないだけです ...まだ.

しかし、それは機能するので、上記のステートメントは次のように壊れていると想定しました。

はい、初期化されていないポインターを同じ型に変換するだけです。つまり、変換は必要ないため、コンパイラーは何もしません。ポインターは同じ型のままで、まだ初期化されていません。

これは次のようになります。

int i = i;

これは、その時点でスコープ内にあるため、C++ の文法に従って有効ですiが、初期化されていないオブジェクトをコピーするため未定義です。実際にコンピュータに火をつける可能性は低いですが、「動作」しているように見えます。

誰かがこれらがどのように機能しているのか詳しく説明してもらえますか?

技術的には、未定義の動作である無効なポインターを逆参照していますが、メンバー関数は実際にはオブジェクトのメンバーを使用しないため、無効なthisポインターは逆参照されないため、コードは「機能します」(または少なくとも. )

これは次のようになります。

void function(A* that)
{
    std::cout << "Hello, world!\n";
}
A* p;
function(p);

thatポインターが使用されていない (メンバー関数でポインターが使用されていないなど)ためthis、必ずしもクラッシュするわけではありませんが、初期化されていないポインターをコピーしてもハードウェア障害が発生する可能性がある実装ではクラッシュする可能性があります。あなたの例では、コンパイラがabc非静的メンバー関数を呼び出すために逆参照する必要はないようです。隠しthisパラメーターとして渡すとハードウェア障害は発生しませんが、動作は失敗しませんが未定義ですセグメンテーション違反などの明らかな方法で..

于 2013-03-06T14:42:42.727 に答える
3

abc初期化されておらず、メモリ内の未定義の場所を指していますが、メソッドは何も読み取らない*thisため、クラッシュしません。

ただし、クラッシュしないという事実は、ほぼ確実に実装定義の動作です。

于 2013-03-06T14:42:13.433 に答える