静态成员和继承
Posted
技术标签:
【中文标题】静态成员和继承【英文标题】:Static member and inheritance 【发布时间】:2009-05-24 08:49:26 【问题描述】:我有一个有成员 m_preferences
的类(一个包含单词和特征之间关联的向量)。
在此类中,m_preferences
不是静态的,因此该类的任何实例都有其特定的 m_preferences
。
class Base
private:
Preferences m_preferences;
public:
...
然后我创建了一个派生类,其中m_preferences
变为静态,因为我希望这个类的每个新实例无论发生什么都共享相同的首选项数据。
class Derived: public Base
private:
static Preferences m_preferences;
public:
...
我遇到了链接错误。
是否可以做我想做的事情(通过继承将非静态成员转换为静态成员)?
如果不是,这种不可能背后的哲学是什么?是计划好的吗?
谢谢,
此致,
罗南
【问题讨论】:
对象是什么?似乎您可能遇到了设计问题,并且您走错了路,撞到了这堵墙。 【参考方案1】:您不能阻止 Base
的每个实例 - 包括 Derived
的每个实例 - 都拥有每个实例的 Preferences 成员变量,因为这是由 Base 类的定义保证的。
您所做的是向Derived
类添加了一个新的静态Preferences
成员,这意味着除了与基类关联的每个实例Preferences
成员之外,您还有一个全局Preferences
实例在所有Derived
实例之间共享。
因为您为这两个成员使用了相同的名称,所以在Parent
成员函数的上下文中,使用标识符m_preferences
将引用全局共享实例,除非您将其限定为Base::m_preferences
。
您的链接错误可能是因为您需要在一个翻译单元中提供Derived::m_preferences
的定义。
例如在 some.cpp 中,在任何函数体之外:
Preferences Derived::m_preferences;
【讨论】:
【参考方案2】:简短回答:您没有正确使用继承。
长答案:您将 Base 定义为具有单独首选项的类型。如果 Derived 不符合“is-a”条件(Derived 是一种也具有每个实例首选项的类型),则它不应该从 Base 继承。
也许是更好的设计(?):
class NotDerivedAnymore
private:
static Base m_base;
public:
...
【讨论】:
【参考方案3】:如果我没看错,您想定义一个对象层次结构,该层次结构将具有静态或单独的实例变量 Preferences。试试这个?
class Base
virtual ~Base();
virtual Preferences& MyPreferences() =0;
;
class DerivedA: public Base
public:
virtual ~DerivedA();
virtual Preferences& MyPreferences() return m_preferences;
private:
Preferences m_preferences;
;
class DerivedB: public Base
public:
virtual ~DerivedB();
virtual Preferences& MyPreferences() return preferences;
private:
static Preferences preferences;
;
Preferences DerivedB::preferences;
“变形”,正如Ali Shafai 所说,是不可能的。这里的问题是“静态”成员是类本身的属性而不是单个对象的属性,而虚拟声明和继承是关于在更高的抽象级别上统一处理可能不属于同一类的单个对象。
【讨论】:
【参考方案4】:是的,根据设计,您不能在继承成员时更改其签名。
【讨论】:
【参考方案5】:您正在破坏 is-a 继承规则。
您说Base
是一个具有自己的Preferences
成员的类型,并且您说Derived
是一个 Base
。
您的 Base
和 Derived
对象似乎有一些共同点,但不是直接继承
相信这也能得到你想要的结果
class TrueBase
// Put data and functionality here that really is common for both types.
private:
virtual Preferences& get_preferences() = 0;
;
class Base : public TrueBase
private:
virtual Preferences& get_preferences()
return m_preferences;
Preferences m_preferences;
;
class Derived: public TrueBase
private:
virtual Preferences& get_preferences()
return m_preferences;
static Preferences m_preferences;
;
【讨论】:
以上是关于静态成员和继承的主要内容,如果未能解决你的问题,请参考以下文章
Java类的各种成员初始化顺序如:父子类继承时的静态代码块,普通代码块,静态方法,构造方法,等先后顺