2009-09-04 18 views
1

次のコードが有効でない理由を説明できますか?変数dのオフセットがbという変数と異なるためですか? 関数を呼び出す際にエラーが発生し、派生型の参照先ポインタを渡す

class Base { public: int foo; }; 

class Derived : public Base { public: int bar; }; 

int DoSomething(Base*& b) { return b->foo; } 

Base* b = new Derived; 
Derived* d = new Derived; 

int main() 
{ 
    DoSomething(d); 
} 

この

the online Comeau C++ compilerが与えるエラーです:

"ComeauTest.c", line 12: error: a reference of type "Base *&" (not const-qualified) 
      cannot be initialized with a value of type "Derived *" 
    DoSomething(d); 
       ^

これは、同様の質問ですが、理由は私の例では異なっている、私はポインタ型としてdを宣言しています:Passing references to pointers in C++

注意bDoSomethingに渡すとコンパイルされます。

答えて

10

あなたがそれを行うことができると想像してください。参照はconstではないので、DoSomethingがポインタに割り当てることが可能であり、呼び出し側でその参照が表示されます。特にDoSomethingの内部では、ポインタがDerivedのインスタンスではないものを指すように変更することが可能です。呼び出し元が、返された後、ポインタに派生固有のものを実行しようとすると、爆発します。

3

これはオフセットとは関係ありません。あなたの例のDerivedはフィールドとしてfoobarの両方を持っていることに注意してください(そうですが、それらは異なるオフセットを持ちますが、これはここでは無関係です)。

これが許可されていれば、タイプセーフではありません。このコードを考えてみましょう:

class Base { public: int foo; }; 

class Derived1 : public Base { public: int bar; }; 

class Derived2 : public Base { public: float baz; }; 

void DoSomething(Base*& b) { b = new Derived2; } 

Derived1* d = new Derived1; 
DoSomething(d); // d is of type Derived1*, but now points to object 
       // of incompatible type Derived2 
3

と仮定doSomethingのは、次のように定義されていました:

int DoSomething(Base*& b) { b = new Base; } 

おっと、doSomethingのを呼び出したときに、メイン今、dはベースを指し終わると、すべての派生したものではありません。

関連する問題