I am learning CRTP C++ pattern
My code
template<class Type>
class BaseOrder {
public:
void sendOrder() {static_cast<Type*>(this)->send();}
void send() { cout << "Send Base" << endl;}
};
class DerivedOrder1 : public BaseOrder<DerivedOrder1> {
public:
void send() { cout << "Send DerivedOrder1" << endl;}
};
class DerivedOrder2 : public BaseOrder<DerivedOrder2> {
public:
void send() { cout << "Send DerivedOrder2" << endl;}
};
template<class T>
void handleOrder(BaseOrder<T> order) {
order.send();
}
int main() {
BaseOrder<DerivedOrder1> obj1;
handleOrder(obj1); // Send Base
BaseOrder<DerivedOrder2> obj2;
handleOrder(obj2); // Send Base
}
I see output:
Send Base
Send Base
But I expect
Send DerivedOrder1
Send DerivedOrder2
How to fix my code? Did I miss something?
There are several mistakes in your code:
send
is not virtual
, you probably want to call sendOrder
instead.
and you should pass that argument by reference to avoid slicing which would make the call to sendOrder
UB as the cast would be invalid:
template <class T>
void handleOrder(BaseOrder<T>& order) {
order.sendOrder();
}
in main, you don't create the derived class, it should be
DerivedOrder1 obj1;
handleOrder(obj1); // Send Base
DerivedOrder2 obj2;
handleOrder(obj2); // Send Base
An improvement to avoid those mistakes would be to make some methods protected
:
template<class Type>
class BaseOrder {
protected:
BaseOrder() = default;
BaseOrder(const BaseOrder&) = default;
BaseOrder& operator=(const BaseOrder&) = default;
public:
// ..
};