Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/127.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 多态性:访问继承的类变量_C++ - Fatal编程技术网

C++ 多态性:访问继承的类变量

C++ 多态性:访问继承的类变量,c++,C++,我有一个从抽象基类继承的类 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;

我有一个从抽象基类继承的类

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,我认为它可以正常工作,但由于某些原因,它不允许我声明虚拟数据成员。解决这个问题的推荐方法是什么?感谢您的帮助。

您应该从基类公开继承:

class CStateTitle: public CStateBase
否则,从编译器的角度来看,
cstatetile
不是
CStateBase
,因此不能通过
CStateBase
指针以多态方式访问
cstatetile
对象


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

最好的方法是将
m\u iR
的访问抽象为一些虚拟函数

另一种选择是将
m_iR
cstatetile
移动到
CStateBase
。只有当每个类都需要
m\u 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
}
CStateBase*csb=。。。;
CStateTitle*cst=动态施法(csb);
国际单项体育联合会(cst)
{
//拥有有效的CStateTitle
}
其他的
{
//csb没有指向CStateTitle,请做任何适当的事情
}

由于您试图直接从基类指针访问派生类的成员,因此显然没有调用多态性。因此,您可以使用
dynamic\u cast
访问该成员


主动建议:不要直接访问成员变量。考虑您的层次结构,以及如何使用某种一致的接口使用虚拟方法访问您试图完成的操作。

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

不能有虚拟成员变量

您可以在施放时更改:

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;
CStateBase*a=新的cstatetTitle();
CStateTitle*b=动态演员阵容(a);
if(NULL!=b)
b->m_iR=1;

或者在基类上添加一个虚拟setter方法,如果所有CStateBase都需要设置一些int。

您很可能希望基类中有一个虚拟析构函数,请参见例如Sutters。普通的非虚拟成员变量以什么方式不能解决您的问题?您的最终想法是完全正确的,但如果可能的话,应该避免。这是一个危险信号,表明你没有充分考虑你的多态性。MarkRandom-我同意你的观点,这就是为什么我把这个选项放在最后的原因。为了强调这一点,我将措辞改为“最后手段”。