虚拟非方法成员

时间:2009-10-17 05:40:58

标签: c++ virtual

有类似的可能吗?这样就会产生错误。

class A {
    public:
    virtual std::string key;
};

class B : public A {
    public:
    std::string key;
};

int main()
{
    A a;
    a.key = "Foo";
    return 1;
}

2 个答案:

答案 0 :(得分:8)

不,因为这没有多大意义。请记住,子类包含其父类的所有成员;因此,B仍然有Astd::string key。此外,由于B的{​​{1}}属于同一类型,因此它与<{1}}的完全相同< - em> - 所以重写它的重点是什么?

另外,请注意在构造期间,当我们运行std::string key的构造函数时,将不会调用A的虚方法。这意味着,如果我们在A构建期间访问B,我们会获得key的密钥 - 但是当构建A时,A将被遮蔽,其数据完全无法访问。

那就是说,如果你真的想做这样的事情,出于某种原因,你需要使用虚拟访问器功能:

B

答案 1 :(得分:0)

类方法是代码。代码是不变的。每个特定的类方法都具有在编译时定义的预定义的固定行为,该行为在运行时无法更改。出于这个原因,为了拥有多态类,我们必须提前编写不同方法的许多不同版本(即在编译时),然后在运行时将这些版本的特定集合“附加”到类实例,从而形成每个实例的特定运行时行为。

对于数据成员,情况完全不同。数据成员不是固定的。它们是多变的。它们保存值,这些值可以在运行时自由更改。仅这一点就使数据成员本身就具有“虚拟化”。您不需要在派生类中引入不同的“版本”数据成员。相反,您只需将不同的值放入已存在的数据成员中。仅此一点已经类似于类方法的“虚拟性”。此外,这种“数据虚拟性”比方法的“虚拟性”更灵活,因为对于数据成员,您不限于预先确定的一组值。

你提出的建议虽然看起来更高程度的“虚拟性”:不仅数据成员的价值是可变的,而且数据成员本身是可以覆盖的。 (称之为元虚拟性,或超虚拟性或双重虚拟性。)但是,具有此功能的重点,好处和用例是什么?我个人没有立刻看到它,你的代码示例并不完全正确。