假设我已经基于一个基本类定义了两个类:
class Basic
{
public:
int i;
};
class DerivedA:public Basic
{
public:
int j;
};
class DerivedB:public Basic
{
public:
int k;
};
然后现在有一个名为Collect的类,它包含指向Basic
类
class Collect
{
public:
Basic *pBasic;
void run();
};
在这个类中,定义了一个函数run()
,它将根据指针指向的对象类型执行一些操作:
void Collect::run()
{
if (pBasic points to DerivedA object)
{
}
if (pBasic points to DerivedB object)
{
}
};
然后我的问题如下:
run
函数中所示的指针所指向的对象类型执行不同的操作是不错的做法? 答案 0 :(得分:3)
要执行这样的检查,您的基类Basic
需要至少有一个虚拟成员。由于您希望构建一个类层次结构,我倾向于使~Basic
虚拟,以确保它同时为properly deleted。
这背后的原因是,通过包含virtual
成员,您强制类的每个对象包含指向特定类vtable的指针,然后实现可以使用它来执行检查。
class Basic
{
public:
int i;
virtual ~Basic() { }
};
class DerivedA:public Basic
{
public:
int j;
};
class DerivedB:public Basic
{
public:
int k;
};
现在你可以写支票了:
void Collect::run()
{
if (DerivedA* pDerived = dynamic_cast<DerivedA*>(pBasic)) { }
if (DerivedB* pDerived = dynamic_cast<DerivedB*>(pBasic)) { }
};
如果dynamic_cast
失败,nullptr
将返回if
,因此当您的演员成功并且pDerived
包含有效指针时,您只会输入{{1}}的正文正确的派生对象。
答案 1 :(得分:0)
在c ++中,我们通常使用 Base 类,而不是Basic类。
无论如何,一般来说,如果您的基类是多态的(包含虚函数),您可以使用dynamic_cast:
class Base {
public:
Base();
virtual ~Base();
void test() { cout << "Base" ; }
};
class Derived: public Base {
public:
void test() { cout << "Derived" ; }
};
void main() {
Base* a = new Derived();
if(dynamic_cast<Derived*>(a)) {
a->test(); /* print "Derived" */
}
}
这意味着对象“a”具有“静态类型”:Base;和“动态类型”:派生。
答案 2 :(得分:0)
除非您的基类具有虚函数,否则指针的指针将始终为Basic
类型,并具有类型为Basic
的对象的行为。实际上,即使使用虚函数,类型为Basic*
的指针也始终指向类型为Basic
的对象。但是动态类型&#39;&#39;&#39;&#39;指针可以是不同的。
如果您的基类至少有一个虚函数,那么您可以依赖Run-time type information:您可以使用dynamic_cast
或typeid
来获取指针的动态类型。< / p>