【发布时间】:2013-10-10 08:31:42
【问题描述】:
下面有一个代码sn-p:
#include <iostream>
using namespace std;
class Base {
public:
Base() : b(0) {}
int get();
virtual void sayhello() { cout << "Hello from Base with b: " << b << endl; }
private:
int b;
};
int Base::get() {sayhello(); return b;}
class Derived : public Base {
public:
Derived(double b_):b(b_){}
void sayhello() { cout << "Hello from Derived with b: " << b << endl; }
private:
double b;
};
int main() {
Derived d(10.0);
Base b = d;
cout << "Derived b: " << d.get() << endl;
cout << "Base b: " << b.get() << endl;
}
运行编译后的可执行文件,我发现结果在我的 llvm-g++ 4.2 机器上超出了我的预期。我的盒子上的输出是
Hello from Derived with b: 10
Derived b: 0
Hello from Base with b: 0
Base b: 0
我想要在代码中做的是覆盖Derived 类中的成员字段(b)。
由于我认为Base 和Derived 都需要访问这个字段,所以我在Base 中定义了一个get 成员函数,因此Derived 可以继承它。
然后我尝试从不同的对象中获取成员字段。
结果显示,我仍然通过d.get() 在Base 中获得原始b,而不是在Derived 中,这是我期望代码执行的操作。
代码(或我的理解)有什么问题吗?规范中是否指定了此行为?覆盖成员字段并正确定义其 getter 和 setter 的正确方法是什么?
【问题讨论】:
-
为什么这个结果会出乎你的意料?除非它是合格的,否则您正在从
D隐藏B::b。但是D的隐藏的、已初始化的 B::b 成员被B的默认 copy-ctor 复制,因为它应该是。您的基类不只是通过某种渗透开始使用它们的非隐藏派生类成员变量。他们甚至不知道他们在那里。