检测我们是否在子类或基类中

时间:2015-04-20 11:59:03

标签: c++ typeid

我遇到了问题,我尝试使用RTTI来解决它。

我有一个班级Base和子班级(在这个例子中,我只展示了一个Child

class Base {
    virtual void Eval() {

      // normal treatment
              +
      // treatment only for Base instance
    }
};

class Child : Base {
    void Eval() {
      // call Base Eval
      Base::Eval();
      //other treatment
    }
};

问题在于Base::Eval,当我从Child调用它时,有一些我不想执行的处理方法。 我的意思是,在Child::Eval中,当我们调用Base::Eval时,我们只需要执行正常处理。

为此,我想到了RTTI。我不知道这是否是使用它的最佳方式,我想做这样的事情:

class Base {
        virtual void Eval() {

          // normal treatment
                  +
          if (typeid(this).name() == typeid(Base).name()) {         
            // treatment only for Base instance
          }
        }
    }

问题是:是否允许这样做? 我有责任查看typeid.name()吗? 或者只是typeid()是否足够?

1 个答案:

答案 0 :(得分:10)

这种情况几乎总是表明设计糟糕。基类不应该知道它的派生类。

如果要为派生类提供自定义部分基本行为的选项,请使用虚函数和"模板方法"设计模式:

class Base
{
public:
  virtual void Eval() {
    // normal treatment
    Eval_CustomisationHook();
  }

protected:
  virtual void Eval_CustomisationHook()
  {
    // Do the stuff
  }
};

class Child : public Base
{
protected:
  virtual void Eval_CustomisationHook()
  {} // do nothing
};

或者,您可以只委派查询:

class Base
{
public:
  virtual void Eval() {
    // normal treatment
    if (doOptionalEvalPart()) {
      // do it here
    }
  }

protected:
  virtual bool doOptionalEvalPart()
  {
    return true;
  }
};

class Child : public Base
{
protected:
  virtual bool doOptionalEvalPart()
  {
    return false;
  }
};

并回答你原来的问题:正确的形式是比较std::type_info个对象,而不是它们的名字。并且不要忘记你必须解除引用this。所以代码看起来像这样:

if (typeid(*this) == typeid(Base))

这将做你想要的。但正如我上面所说,这很可能不是正确的做法。