The client doesn't necessarily have to be aware of the concrete type. For example, consider this hierarchy:
struct Base
{
virtual ~Base();
virtual Base * clone() const = 0;
static Base * create(std::string const &);
// ...
};
struct A : Base { A * clone() const { return new A(*this); } /* ... */ };
struct B : Base { B * clone() const { return new B(*this); } /* ... */ };
struct C : Base { C * clone() const { return new C(*this); } /* ... */ };
Base * Base::create(std::string const & id)
{
if (id == "MakeA") return new A;
else return new C;
};
In this case, the client can make and copy an existing object like so:
Base * p = Base::create("IWantB"); // or std::unique_ptr<Base> !
Base * q = p->clone();
In neither case does the client ever know the dynamic type of *p
or *q
.