如何知道指针在C ++中指向的对象类型?

时间:2014-04-28 15:14:02

标签: c++

假设我已经基于一个基本类定义了两个类:

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)
  {

   }

};

然后我的问题如下:

  • 使用C ++,是否可以知道指针指向的对象类型?
  • 根据run函数中所示的指针所指向的对象类型执行不同的操作是不错的做法?

3 个答案:

答案 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_casttypeid来获取指针的动态类型。< / p>