Reputation: 22173
I want to know if a child class did an override of a virtual method, in this case I want to insert the instance in a special list for additional processing. What I have until now using CRTP:
template<class T>
class P {
public:
P() {
if (!std::is_same<decltype(&T::foo),decltype(&P::foo)>::value)
.........do something.........
}
virtual ~P(){}
virtual void foo() {}
}
class Child: public P<Child> {
public:
Child() {
}
virtual void foo() {
}
}
I want to know if there's some tricks to avoid the CRTP in this case, because currently P class is not a template and I should change several lines of codes. I could but I want to know if there are alternatives. I tried to use the same schema but just in another function, not in the P constructor, but I should iterate over any single child of P (I have several child classes). Is it possible to "iterate over types"? I have a list of P pointers, but obviously a runtime check is deeply different from a static check like std::is_same. I tried to use:
(void*)(obj.*(&P::foo)) != (void*)(&P::foo)
and it actually works with gcc 4.8.1 but I should disable the warnings using -Wno-pmf-conversions and it doesn't seem the best choice.
Upvotes: 2
Views: 262
Reputation: 595305
I want to know if a child class did an override of a virtual method
There is no official way to determine that at runtime. You may have to dig into the object's RTTI (if it provides rich enough info for that) or even the vtable directly, or use other compiler-specific tricks to compare methods.
in this case I want to insert the instance in a special list for additional processing.
Then I suggest a different approach for that - use interfaces instead. Declare an abstract class that contains just the virtual method you are interested in, then have your other classes derive from that interface only if they intend to implement the method.
This way, you can use dynamic_cast
to test objects at runtime if they implement the interface or not.
Try something like this:
class Foo
{
public:
virtual void foo() = 0;
};
class P
{
public:
virtual ~P() { }
};
class Child : public P, public Foo
{
public:
Child() { }
void foo() override { }
};
Then you can do something like this:
P *p = new Child;
...
Foo *f = dynamic_cast<Foo*>(p);
if (f) listOfFoos.push_back(f);
...
for (Foo *f : listOfFoos)
f->foo();
...
Upvotes: 2