【问题标题】:How to check if C++ abstract method is defined at runtime如何检查 C++ 抽象方法是否在运行时定义
【发布时间】:2011-05-17 23:58:06
【问题描述】:

如何检查 C++ 抽象方法是否在运行时定义

class ABase{
public:
 virtual void do1() = 0;
};

class BBase: public ABase{
public:
 virtual void do1(){}
};

class CBase: public ABase{
public:
};

ABase * base = rand() % 2 ? new BBase() : new CBase();
if(&(base->do1) != 0)
  base->do1();

这会出错。

谢谢, 最大

【问题讨论】:

  • 没有。又有什么用呢?
  • 这里没有虚方法。请参阅下面的答案。
  • 当然这会产生错误 - 编译错误。还是缺少的virtual 只是一个错字/糊涂,而您是在说还是运行时错误?还是在那个有趣(和错误)的比较中编译错误?如果有,有哪些?用这样一个草率的问题是不可能说的。我投票关闭它,因为它的方式无法得到合理的回答。
  • 整个代码都是假的,它在函数之外声明,你不能获取像&base->do1这样的成员函数的地址,你只能做&ABase::do1,但编写代码的整个前提试图做问题所要求的是错误的。我认为这个问题是可以“回答”的,即使答案必须提出问题。
  • 是的。这种方法在现实生活中是虚拟的。我输入问题时的错误。

标签: c++ methods runtime virtual abstract


【解决方案1】:

由于您无法实例化抽象类,因此您在运行时遇到的任何类都不会有任何纯虚方法(除非您当时处于构造函数或析构函数中),它们都将被覆盖非纯覆盖。没有什么要检查的。

【讨论】:

    【解决方案2】:

    CBase 是抽象的,因为它不会覆盖 ABase::do1()。因此,您无法实例化它。或者更确切地说,如果您将 do1() 声明为虚拟,就会发生这种情况。但目前,它只是无法编译。

    很高兴知道您为什么要这样做。

    【讨论】:

    • 我的错误是虚拟的。 MS VC++ 使用未实现的抽象方法编译类,并且只有在调用抽象方法时我才会在运行时得到接收。我猜 0 被放置在这些方法的 VTABLE 中。
    【解决方案3】:

    必须实现抽象方法才能实例化类。没有检查方法是否被实现这样的事情,编译器会为你做这件事。在这种情况下,您不能拥有 CBase 对象,因为它具有抽象方法。

    【讨论】:

      【解决方案4】:

      您不需要检查该方法是否在运行时实现(在这种情况下无论如何您都不能),因为 CBase 必须实现 do1() 以满足从 ABase 的继承。

      【讨论】:

        【解决方案5】:

        编译器不允许您创建未定义所有抽象方法的类型的实例。在上面的示例中,对 new CBase() 的调用将生成一个编译时错误,类似于“无法实例化抽象类型”。

        【讨论】:

        • MS VC++ 编译它。当我调用这样的方法时,我在运行时遇到异常。 (我在第一篇文章中犯了错误。方法是虚拟的)
        【解决方案6】:

        您不能实例化 CBase,因为它是...抽象的,即不实现其父级的所有纯虚函数。

        最简单的可能是在ABase 中定义一个存根实现:

        class ABase {
        public:
         void do1() { /* do nothing */ }
        };
        
        class BBase: public ABase {
        public:
         void do1() { /* do something */ }
        };
        
        class CBase: public ABase {};
        
        ABase * base = rand() % 2 ? new BBase() : new CBase();
        base->do1();
        

        【讨论】:

          【解决方案7】:

          假设您记得将 do1() 设为虚拟,您可以在运行时检查 &ABase::do1、&BBase::do1 和 &CBase::do1。我不相信比较 &ABase::do1 和 &CBase::do1 会因为 CBase 没有覆盖该函数而返回相同的值,并且是否仅仅因为它在一个系统上就意味着它总是会。

          虽然您可能能够在运行时测试这些,但如果 CBase 类不是抽象的,您将无法使用这些信息来创建对象,因为当它是抽象时它将无法编译。

          您可以改为使用“C”方式:有一个可以为 NULL 的函数指针表,检查其中一个是否为 NULL,并创建此类实例的结构,如果不是则调用它.

          【讨论】:

            猜你喜欢
            • 2019-11-02
            • 1970-01-01
            • 2011-10-26
            • 1970-01-01
            • 2018-05-09
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2011-03-08
            相关资源
            最近更新 更多