4

次のクラスがある場合:

class Foo
{
protected:
    int i;
public:
    Foo() : i(42) {}
};

当然、外部から保護されたメンバーにアクセスすることはできませんが、次の小さなトリックを実行できます。まず、Foo を継承する新しいクラスを作成します。

class Foo2 : public Foo
{
public:
    int GetI() { return i; }
};

これで、Foo のインスタンスまたはそのようなインスタンスへのポインターがある場合はいつでも、キャストを介して保護されたメンバーにアクセスできます (追加のメンバーを使用しないため)。

Foo *f = new Foo();
Foo f2;
std::cout << ((Foo2*)f)->GetI() << std::endl;
std::cout << (reinterpret_cast<Foo2&>(f2)).GetI() << std::endl;

これが機能する理由は理解できますが、悪い結果が生じることはありますか? コンパイラは気にしません。実行時のチェックはありません。

4

2 に答える 2

5
reinterpret_cast<Foo2&>(f2)).GetI()

技術的には、これは未定義の動作です。したがって、うまくいくかもしれませんが、そうする必要はありません。

于 2013-03-16T14:46:59.813 に答える
1

FooオブジェクトをオブジェクトにダウンキャストしていFoo2ます。

ダウンキャストは、基本クラスから派生クラスへのキャストです。ダウンキャストは、実行時にアドレス指定されたオブジェクトが実際に派生クラス オブジェクトをアドレス指定している場合にのみ安全です。

コードを保護するにdynamic_castは、ダウンキャストが有効かどうかを確認するために使用する必要があります。

reinterpret_castダウンキャストの使用はお勧めしません。static_castまたはを使用しdynamic_castます。

記事のチャンクを読んで、多くの人があなたのようにダウンキャスティングを使用しないでください. virtual void GetI()危険な例の 1 つは、 inを持つことですFoo

于 2013-03-16T15:00:14.887 に答える