2010-06-23 151 views
0

我有一个从抽象基类继承的类。多态:访问继承类变量

class CStateBase 
{ 
    friend class CApplication; 
    friend class CGraphics; 
    virtual int Update() =0; 
}; 

class CStateTitle: private CStateBase 
{ 
    friend class CApplication; 
    friend class CGraphics; 
    CApplication *f_App; 

    int m_iR; 

    int Update(); 

    CStateTitle(CApplication *App); 
    ~CStateTitle(); 
}; 

在另一个类的方法中,CStateTitle被动态分配到CStateBase指针中。但是,如果我使用该指针尝试访问变量int m_iR,则编译器将在CStateBase中查找变量,并因此发生错误。如果我可以在基类中声明virtual int m_iR,我认为它可以正常工作,但由于某种原因,它不会让我声明虚拟数据成员。推荐解决此问题的方法是什么?谢谢你的帮助。

+0

您很可能想要在您的基类中使用虚拟析构函数,请参阅Sutters [Virtuality](http://www.gotw.ca/publications/mill18.htm)。 – 2010-06-23 22:41:07

+1

普通的非虚拟成员变量以何种方式不能解决您的问题? – 2010-06-23 22:42:20

回答

3

最好的办法是将m_iR的访问抽象成一些虚函数。

另一种选择是将m_iRCStateTitle移动到CStateBase。这只有在每个班级需要m_iR才有意义。

不得已是做一个动态转换:

CStateBase *csb = ...; 

CStateTitle *cst = dynamic_cast<CStateTitle *>(csb); 
if (cst) 
{ 
    // have a valid CStateTitle 
} 
else 
{ 
    // csb is not pointing at a CStateTitle, do whatever is appropriate 
} 
+2

你的最终想法是完全有效的,但应尽可能避免。这是一个红旗,说你没有把足够的思想放入你的多态。 – 2010-06-23 22:49:23

+0

@MarkRandom - 我同意你的看法,这就是为什么我最后选择了这个选项。我已经把我的措辞改为“最后的手段”来强调这一点。 – 2010-06-23 23:48:57

5

你应该从基类继承公开:

class CStateTitle: public CStateBase 

否则CStateTitle不是但从编译器的点CStateBase,因此,您可以通过CStateBase指针没有多态访问CStateTitle对象。

您不能拥有虚拟数据成员,只能使用C++中的虚拟方法。因此,解决方法可能是为数据成员声明虚拟访问器方法。

1

既然你想直接从基类指针访问派生类的成员,你显然不是调用多态性。因此,您可以使用dynamic_cast访问该成员。

未经请求的建议:不要直接访问成员变量。考虑您的层次结构以及您尝试完成的操作如何使用某种使用虚拟方法的一致性界面进行访问。

0

您可以在基类中定义一个虚函数来执行所需的acccess(getter和/或setter),或者,您必须将基指针转换为派生*并从那里继续。

1

你不能有虚拟成员变量。如果所有CStateBase那里将会有一些

CStateTitle *a = new CStateTitle(); 
a->m_iR = 1; 
CStateBase *b = a; 

或再晚些时候使用RTTI

CStateBase *a = new CStateTitle(); 
CStateTitle *b = dynamic_cast<CStateTitle*>(a); 
if(NULL != b) 
    b->m_iR = 1; 

投或基类中添加一个虚拟的setter方法:

你可以当你施放改变int需要设置。