c++ - 检测我们是在子类还是基类

标签 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() 就足够了?

最佳答案

诸如此类的情况几乎总是表明设计不当。基类不应知道其派生类的任何信息。

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

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
};

或者,您可以只委托(delegate)查询:

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

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

关于c++ - 检测我们是在子类还是基类,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29747290/

相关文章:

c++ - gdb:显示一些数据的类型信息

c++是否可以将对象类型传递给要与之比较的函数

c++ - 虚拟成员函数更改 typeid 的结果 - 为什么?

python - 如何在 boost python 中公开采用可变参数的 C++ 函数

C++ 在基类中使用静态数组,在派生类中声明

c++ - 测试 C++ 应用程序的性能

c++ - 根据模板变量类型执行不同的方法

c++ - 不能声明指向“struct tm&”的指针

c++ - C++ 中的错误,该怎么办?:找不到 ostream::write(long *, unsigned int) 的匹配项

C++ typeid.name() 只返回 char "c"