有人可以解释为什么以下代码无效吗?是因为名为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++
请注意,当我将b
传递给DoSomething
时,这会编译。
答案 0 :(得分:10)
想象一下,你可以做到这一点。引用不是const,因此DoSomething可以分配给指针,并且可以在调用者中看到。特别是,在DoSomething中,我们可以将指针更改为指向不是Derived实例的指针。如果调用者在我们返回后尝试对指针执行特定于派生的事情,它将会爆炸。
答案 1 :(得分:3)
这与抵消无关。请注意,您的示例中的Derived
同时包含foo
和bar
作为字段(是的,它们将具有不同的偏移量,但这在此处无关紧要。)
如果允许这样做,那就不是类型安全的。请考虑以下代码:
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
答案 2 :(得分:3)
假设DoSomething的定义如下:
int DoSomething( Base*& b ) { b = new Base; }
糟糕,现在主要调用DoSomething时,d最终指向Base而不是Derived。