mirror of
https://github.com/isocpp/CppCoreGuidelines.git
synced 2024-03-22 13:30:58 +08:00
T.5: Add an example for Type erasure (#1625)
Based on : https://www.modernescpp.com/index.php/c-core-guidelines-type-erasure-with-templates Co-authored-by: Vincent Legarrec <vincent.legarrec@csdental.com>
This commit is contained in:
parent
d4e2281a09
commit
6d17d10604
|
@ -16829,6 +16829,47 @@ Static helps dynamic: Use static polymorphism to implement dynamically polymorph
|
|||
Dynamic helps static: Offer a generic, comfortable, statically bound interface, but internally dispatch dynamically, so you offer a uniform object layout.
|
||||
Examples include type erasure as with `std::shared_ptr`'s deleter (but [don't overuse type erasure](#Rt-erasure)).
|
||||
|
||||
#include <memory>
|
||||
|
||||
class Object {
|
||||
public:
|
||||
template<typename T>
|
||||
Object(T&& obj)
|
||||
: concept_(std::make_shared<ConcreteCommand<T>>(std::forward<T>(obj))) {}
|
||||
|
||||
int get_id() const { return concept_->get_id(); }
|
||||
|
||||
private:
|
||||
struct Command {
|
||||
virtual ~Command() {}
|
||||
virtual int get_id() const = 0;
|
||||
};
|
||||
|
||||
template<typename T>
|
||||
struct ConcreteCommand final : Command {
|
||||
ConcreteCommand(T&& obj) noexcept : object_(std::forward<T>(obj)) {}
|
||||
int get_id() const final { return object_.get_id(); }
|
||||
|
||||
private:
|
||||
T object_;
|
||||
};
|
||||
|
||||
std::shared_ptr<Command> concept_;
|
||||
};
|
||||
|
||||
class Bar {
|
||||
public:
|
||||
int get_id() const { return 1; }
|
||||
};
|
||||
|
||||
struct Foo {
|
||||
public:
|
||||
int get_id() const { return 2; }
|
||||
};
|
||||
|
||||
Object o(Bar{});
|
||||
Object o2(Foo{});
|
||||
|
||||
##### Note
|
||||
|
||||
In a class template, non-virtual functions are only instantiated if they're used -- but virtual functions are instantiated every time.
|
||||
|
|
Loading…
Reference in New Issue
Block a user