Consider the code:
#include <iostream>
class A {
public:
void g() {std::cout << "Call from A" << std::endl;}
void f() {g();}
};
class B : public A {
public:
void g() {std::cout << "Call from B" << std::endl;}
};
int main() {
B b;
b.f(); // "Call from A"
}
If I make A::g()
virtual, it outputs "Call from B".
I always understood "virtual" useful when we want an interface to allow polymorphism, say A *a = new B(); a->f()
, but this example indicates that virtual
is also required in this situation. My understanding of this example is that the call g()
on A::f
is formally equivalent to this->g()
, and this is a pointer.
However, this is not what I really wanted: in my real example, I have a general template class A with a general method A::simulate
(say A::f
), that uses different methods (say A::g()
), some of which are overwritten by subclass (say B
). What I wanted was to have the method A::simulate
in such a way that the code would be compiled in the subclasses of A as if it has been defined on the subclasses so I don't have the same logic coded multiple-times. How can I do this?
This is because my interface will not require polymorphism because the user will always need to compile the code (i.e. it is header only).
You can simply make your base class a CRTP (as you've mentioned it's already a templated class anyway):
#include <iostream>
template<class Derived>
class A {
public:
void g() {std::cout << "Call from A" << std::endl;}
void f() { static_cast<Derived*>(this)->g();}
// ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ Call g() from Derived
};
class B : public A<B> {
public:
void g() {std::cout << "Call from B" << std::endl;}
};
int main() {
B b;
b.f(); // "Call from B"
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With