1 Dynamic binding, polymorphism
class CounterBase {
public:
CounterBase() = default;
virtual ~CounterBase() = default;
virtual void Increment() { count_++; }
int count() const { return count_; }
protected:
int count_ = 0;
};
class CounterDouble : public CounterBase {
public:
CounterDouble() : CounterBase() {}
virtual ~CounterDouble() = default;
void Increment() { count_ += 2; }
};
int main() {
{
CounterDouble counter_double;
CounterBase& counter_base = counter_double; // Polymorphism with reference.
counter_base.Increment();
cout << counter_base.count() << endl; // 2.
}
{
CounterDouble counter_double;
CounterBase* counter_base = &counter_double; // Polymorphism with pointer.
counter_base->Increment();
cout << counter_base->count() << endl; // 2.
}
// If there is no virtual for the function in base class, there will be no polymorphism.
// Dynamic binding condition:
// (1) virtual function
// (2) inherit
// (3) assign derive type to base type with pointer or reference.
return 0;
}
2 Curiously Recursive Template Pattern(CRTP)
template <typename Derived>
class CounterBase {
public:
CounterBase() = default;
virtual ~CounterBase() = default;
// CRTP: compile-time polymorphism, static binding, better performance than dynamic binding.
// Define the interface, and derived class must implement them.
void increment() { static_cast<Derived*>(this)->increment_impl(); }
int count() const { return static_cast<const Derived*>(this)->count_impl(); }
};
class CounterDouble : public CounterBase<CounterDouble> {
public:
CounterDouble() : CounterBase<CounterDouble>() {}
virtual ~CounterDouble() = default;
void increment_impl() { count_ += 2; }
int count_impl() const { return count_; }
private:
int count_ = 0;
};
int main() {
{
CounterDouble counter_double;
CounterBase<CounterDouble>& counter_base = counter_double; // CRTP
counter_base.increment();
cout << counter_base.count() << endl; // 2.
}
{
CounterDouble counter_double;
CounterBase<CounterDouble>* counter_base = &counter_double; // CRTP
counter_base->increment();
cout << counter_base->count() << endl; // 2.
}
return 0;
}
3 Difference between them
- CRTP has better performance than dynamic binding polymorphism(spped: 10X faster in benchmark)
- But CRTP is not so flexible compared to dynamic binding polymorphism.
版权声明:本文为qq_23225073原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。