如何检查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();
这会产生错误。
谢谢, 最大
答案 0 :(得分:14)
由于你无法实例化一个抽象类,你在运行时遇到的任何类都没有任何纯虚方法(除非你当时在构造函数或析构函数中),它们都被覆盖了非纯粹的覆盖。没有什么可以检查的。
答案 1 :(得分:4)
必须实现抽象方法才能实例化类。没有检查方法是否已实现,编译器将为您执行此操作。在这种情况下,您不能拥有CBase对象,因为它具有抽象方法。
答案 2 :(得分:3)
CBase是抽象的,因为它不会覆盖ABase :: do1()。因此,您无法实例化它。或者更确切地说,如果您将do1()声明为虚拟,那将会发生什么。但就目前而言,它只是不会编译。
很高兴知道你为什么要这样做。
答案 3 :(得分:3)
编译器不允许您创建未定义所有抽象方法的类型的实例。在上面的示例中,对 new CBase()的调用将沿着“无法实例化抽象类型”的行生成编译时错误。
答案 4 :(得分:1)
您不需要检查方法是否在运行时实现(在这种情况下无论如何都不能),因为CBase 必须实现do1()以满足继承ABase。
答案 5 :(得分:1)
你无法实例化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();
答案 6 :(得分:1)
假设您记得make do1()virtual,您可以在运行时检查& ABase :: do1,& BBase :: do1和& CBase :: do1。我不相信比较& ABase :: do1和& CBase :: do1将返回相同的值只是因为CBase没有覆盖该函数,并且是否因为它在一个系统上执行意味着它总是会。
虽然您可以在运行时测试这些信息,但如果它不是抽象的,则无法使用该信息来创建类CBase的对象,因为它将无法编译。
你可以改为“C”方式:有一个函数指针表可以为NULL,检查其中一个是否为NULL,并创建这样一个实例的结构,如果不是,则调用它