2009-10-17 79 views
1

是否有类似于此的可能?这样它会产生一个错误。虚拟非方法成员

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

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

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

目前还不清楚你正在寻找什么样的行为。如果您在main()函数中添加更多代码来解释您要查找的行为,这将有所帮助。 不,它使虚拟数据成员没有意义。 – zumalifeguard 2009-10-17 05:47:06

回答

8

不,因为这没有意义。请记住,一个子类包含其父类的所有成员;因此,B仍然有Astd::string key。此外,由于Bstd::string key是同一类型,它是绝对相同的A的 - 所以重写它的意义是什么?

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

也就是说,如果你真的想要做这样的事情,出于某种原因,你需要使用虚拟存取函数:

class A { 
    private: 
    std::string m_key; 
    public: 
    virtual std::string &key() { return m_key; } 
    virtual const std::string &key() const { return m_key; } 
}; 

class B : public A { 
    private: 
    std::string m_key; 
    public: 
    virtual std::string &key() { return m_key; } 
    virtual const std::string &key() const { return m_key; } 
}; 

int main() 
{ 
    B b; 
    b.key() = "Foo"; 
    return 0; 
} 
0

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

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

你的建议虽然看起来像一个更高程度的“虚拟性”:不仅数据成员的值是可变的,而且数据成员本身是可覆盖的。 (称之为元虚拟或超虚拟或双虚拟。)但是,具有这种特性的重点,好处和用途是什么?我个人不会马上看到它,而你的代码示例并不完全可以说明。