How to check if C++ abstract method is defined at runtime
class ABase{开发者_Go百科
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();
This gives error.
Thanks, Max
As you can't instantiate an abstract class, any class you encounter at runtime will not have any pure virtual methods (unless you're in a constructor or destructor at the time), they'll all have been overriden with a non-pure overrider. There is nothing to check.
An abstract method must be implemented in order for the class to be instantiated. There's no such thing as checking whether a method is implemented, the compiler will do this for you. In this case, you can't have a CBase object because it has abstract methods.
The compiler won't let you create an instance of a type that doesn't define all abstract methods. In your example above the call to new CBase() will generate a compile time error along the lines of "cannot instantiate abstract type".
CBase is abstract because it does not override ABase::do1(). Therefore, you cannot instantiate it. Or rather, that's what would happen if you had declared do1() as virtual. But for now, it just won't compile.
Would be nice to know why you want to do this, though.
You don't need to check if the method is implemented at runtime (you can't in this case anyway) because CBase must implement do1() to satisfy inheriting from ABase.
You cannot instantiate the CBase
since it's ... abstract, i.e. does not implement all pure virtual functions of its parents.
The easiest would probably be to define a stub implementation in the 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();
Assuming you remember to make do1() virtual you could check &ABase::do1, &BBase::do1 and &CBase::do1 at runtime. I am not convinced that comparing &ABase::do1 and &CBase::do1 will return the same value just because CBase has not overridden the function, and whether just because it does on one system means it always will.
Whilst you may be able to test these at runtime you would not be able to use the information to create an object of the class CBase if it is not abstract as it will fail to compile when it is.
You could instead do it the "C" way though: have a table of function pointers that can be NULL, check if one of them is NULL, and create a struct of such an instance or invoke it if it isn't.
精彩评论