1

次のコードがあります(仮想関数と static_castから盗まれました):

#include <iostream>

class Base
{
public:
   virtual void foo() { std::cout << "Base::foo() \n"; }
};

class Derived : public Base
{
public:
   virtual void foo() { std::cout << "Derived::foo() \n"; }
};

私が持っている場合:

int main()
{
   Base base;
   Derived& _1 = static_cast<Derived&>(base);
   _1.foo();
}

プリントアウトは次のようになります。Base::foo()

ただし、次の場合:

int main()
{
   Base * base;
   Derived* _1 = static_cast<Derived*>(base);
   _1->foo();
}

プリントアウトは次のようになります。Segmentation fault: 11

正直、どちらもよくわかりません。上記の例に基づいて、 static_cast と virtual メソッドの間の複雑さを誰かが説明できますか? ところで、印刷物を " " にしたい場合はどうすればよいDerived::foo()ですか?

4

4 に答える 4

5

2 番目の例では、ベース ポインターをインスタンス化していないため、segfault が発生します。したがって、呼び出す v-table はありません。試す:

Base * base = new Base();
Derived* _1 = static_cast<Derived*>(base);
_1->foo();

これは Base::foo() を出力します

static_cast は v-table に影響しないため、この質問は意味がありません。ただし、これは非仮想関数でより意味があります。

class Base
{
public:
   void foo() { std::cout << "Base::foo() \n"; }
};

class Derived : public Base
{
public:
    void foo() { std::cout << "Derived::foo() \n"; }
};


int main()
{
   Base base;
   Derived& _1 = static_cast<Derived&>(base);
   _1.foo();
}

これは Derived::foo() を出力します。ただし、これは非常に間違ったコードであり、コンパイルしても動作は未定義です。

于 2013-06-26T18:24:15.297 に答える
2

仮想関数の全体的な目的は、変数の静的型が問題にならないことです。コンパイラは、オブジェクト自体の実際の実装を検索します (通常は、オブジェクト内に隠されている vtable ポインターを使用します)。static_cast効果がないはずです。

于 2013-06-26T18:24:40.160 に答える