Prototype Design Pattern is a Creational Design Pattern that . You can consider the prototype as a of an object before the actual object is constructed. In this article of the Creational Design Patterns, we’re going to take a look at why we need a Prototype Design Pattern in C++ i.e. motivation, prototype factory & leveraging prototype design pattern to implement . helps in the prototyping(creating/copying cheaply) of an object using separate methods or polymorphic classes template virtual copy constructor By the way, If you haven’t check out my other articles on Creational Design Patterns, then here is the list: Factory Builder Prototype Singleton The code snippets you see throughout this series of articles are simplified not sophisticated. So you often see me not using keywords like override, final, public(while inheritance) just to make code compact & consumable(most of the time) in single standard screen size. I also prefer struct instead of class just to save line by not writing “public:” sometimes and also miss , constructor, , prefix std::, deleting dynamic memory, intentionally. I also consider myself a pragmatic person who wants to convey an idea in the simplest way possible rather than the standard way or using Jargons. virtual destructor copy constructor Note: If you stumbled here directly, then I would suggest you go through first, even if it is trivial. I believe it will encourage you to explore more on this topic. What is design pattern? All of this code you encounter in this series of articles are compiled using C++20(though I have used features up to C++17 in most cases). So if you don’t have access to the latest compiler you can use which has preinstalled boost library as well. Modern C++ https://wandbox.org/ Intent To create a new object cheaply with the help of an already constructed or pre-initialized stored object. The prototype provides flexibility to create complex object cheaply. The concept is to copy an existing object rather than creating a new instance from scratch, something that may include costly operations. The existing object then acts as a prototype & newly copied object may change the same properties only if required. This approach saves costly resources and time, especially when the object creation is a heavy process. So essentially the prototype is quite simply a partially or fully initialized object that you make a copy of. And then you subsequently use for your own benefit with variations. Motivation m_street; m_city; m_cubical; Office( s, c, n):m_street(s), m_city(c), m_cubical(n){} }; m_name; Office m_office; Employee( n, Office o):m_name(n), m_office(o){} }; { Employee john{ , Office{ , , } }; Employee jane{ , Office{ , , } }; Employee jack{ , Office{ , , } }; EXIT_SUCCESS; } { struct Office string string int32_t string string int32_t { struct Employee string string int main () "John Doe" "123 East Dr" "London" 123 "Jane Doe" "123 East Dr" "London" 124 "jack Doe" "123 ORR" "Bangaluru" 300 return This is not the right approach as you have to write the main office address again & again for each employee detail. This is cumbersome & become more when you want to create an employee list. Moreover, consider the situation when your main office moved to another address. Prototype Design Pattern Examples in C++ A more pragmatic approach would be like this : m_name; Office* m_office; Employee( n, Office *o):m_name(n), m_office(o){} }; Office LondonOffice{ , , }; Office BangaluruOffice{ , , }; { Employee john{ , &LondonOffice }; Employee jane{ , &LondonOffice }; Employee jack{ , &BangaluruOffice }; EXIT_SUCCESS; } { struct Employee string const string static "123 East Dr" "London" 123 static "RMZ Ecoworld ORR" "London" 123 int main () "John Doe" "Jane Doe" "jack Doe" return Above solution is suitable for our use case but sometimes we want to customize that office address. And when it comes to pointers & references and any sort of indirection, ordinary copying using operator equals quite simply does not work. A standard way to implement this is by implementing the copy constructor Prototype Factory So in the previous example of the Prototype Design Pattern, we basically had a global for office addresses and used their address for creating prototypes. object Now, this isn’t particularly convenient to the consumers of your API because you might want to give them a prototype to work with. And you should explicit enough in terms of letting people know there is the only a unified way by which they create instances from a prototype and so that they cannot make individual instances by themselves. And in this case, what you would build is off-course is a Prototype Factory: m_street; m_city; m_cubical; }; m_name; Office* m_office; Employee( n, Office *o) : m_name(n), m_office(o) {} : Employee( Employee &rhs) : m_name{rhs.m_name}, m_office{ Office{*rhs.m_office}} { } Employee& =( Employee &rhs) { ( == &rhs) * ; m_name = rhs.m_name; m_office = Office{*rhs.m_office}; * ; } ostream & <<(ostream &os, Employee &o) { os << o.m_name << << o.m_office->m_street << << o.m_office->m_city << << o.m_office->m_cubical; } }; Employee main; Employee aux; <Employee> NewEmployee( n, c, Employee &proto) { e = make_unique<Employee>(proto); e->m_name = n; e->m_office->m_cubical = c; e; } : <Employee> NewMainOfficeEmployee( name, cubical) { NewEmployee(name, cubical, main); } <Employee> NewAuxOfficeEmployee( name, cubical) { NewEmployee(name, cubical, aux); } }; Employee EmployeeFactory::main{ , Office{ , , }}; Employee EmployeeFactory::aux{ , Office{ , , }}; { jane = EmployeeFactory::NewMainOfficeEmployee( , ); jack = EmployeeFactory::NewAuxOfficeEmployee( , ); << *jane << << *jack << ; EXIT_SUCCESS; } { struct Office string string int32_t { class Employee string // Private constructor, so direct instance can not be created except for `class EmployeeFactory` string friend ; class EmployeeFactory public const new operator const if this return this new return this friend operator const return " works at " " " " seats @" { class EmployeeFactory static static static unique_ptr string int32_t auto return public static unique_ptr string int32_t return static unique_ptr string int32_t return // Static Member Initialization "" new "123 East Dr" "London" 123 "" new "RMZ Ecoworld ORR" "London" 123 int main () auto "Jane Doe" 125 auto "jack Doe" 123 cout endl endl return /* Jane Doe works at 123 East Dr London seats @125 jack Doe works at RMZ Ecoworld ORR London seats @123 */ The subtle thing to note here is the private constructor of Employee & friend EmployeeFactory. This is how we enforce the client/API-user to create an instance of Employee only through EmployeeFactory. Leveraging Prototype Design Pattern to Implement Virtual Copy Constructor In C++, Prototype is also useful to create a copy of an object without knowing its concrete type. Hence, it is also known as Virtual Copy Constructor. Problem C++ has the support of polymorphic object destruction using it’s base class’s . Equivalent support for creation and copying of objects is missing as С++ doesn’t support virtual constructor & virtual . virtual destructor copy constructors Moreover, you can’t create an object unless you know its static type, because the compiler must know the amount of space it needs to allocate. For the same reason, copy of an object also requires its type to known at compile-time. Consider the following example as problem statement: ~animal(){ << ; } }; animal { ~dog(){ << ; } }; animal { ~cat(){ << ; } }; { who; } { struct animal virtual cout "~animal\n" : struct dog cout "~dog\n" : struct cat cout "~cat\n" void who_am_i (animal *who) // not sure whether dog would be passed here or cat // How to `create` the object of same type i.e. pointed by who ? // How to `copy` object of same type i.e. pointed by who ? delete // you can delete appropriate object pointed by who, thanks to virtual destructor Just don’t think of , its code smell. dynamic_cast<> Solution The Virtual Constructor/Copy-Constructor technique allows polymorphic creation & copying of objects in C++ by delegating the act of creation & copying the object to the derived class through the use of virtual methods. Following code is not only implements virtual (i.e. clone()) but also implement virtual constructor(i.e. create()). copy constructor ~animal() = ; :: <animal> create() = ; :: <animal> clone() = ; }; animal { :: <animal> create() { ::make_unique<dog>(); } :: <animal> clone() { ::make_unique<dog>(* ); } }; animal { :: <animal> create() { ::make_unique<cat>(); } :: <animal> clone() { ::make_unique<cat>(* ); } }; { new_who = who->create(); duplicate_who = who->clone(); who; } { struct animal virtual default virtual std unique_ptr 0 virtual std unique_ptr 0 : struct dog std unique_ptr return std std unique_ptr return std this : struct cat std unique_ptr return std std unique_ptr return std this void who_am_i (animal *who) auto // `create` the object of same type i.e. pointed by who ? auto // `copy` object of same type i.e. pointed by who ? delete Benefits of Prototype Design Pattern Prototypes are useful when the object instantiation is expensive, thus avoid expensive “creation from scratch”, and support cheap cloning of a pre-initialized prototype. The prototype provides the flexibility to create highly dynamic systems by defining new behaviour through object & specifying values for an object’s data members at the time of instantiation unlike defining new classes. composition You can simplify the system by producing complex objects more conveniently. Especially in C++, Prototype Design Pattern is helpful in creating copy of an object without even knowing its type. Summary by FAQs What’s the point of using the Prototype Design Pattern? To create an object rapidly based on cloning a pre-configured object. Useful to remove a bunch of boilerplate code. Handly while working with object without knowing its type. Prototype Design Pattern is an obvious choice while you are working with the . For example, in HTTP request most of the time header & footer content remains the same, what changes are data. In such a scenario, you should not create an object from scratch. Rather leverage Prototype Design Pattern. Command Design Pattern Is the Prototype Design Pattern Really Just Clone? It isn’t if you combine it with the . Factory Design Pattern Prototype design pattern to be used when creation is costly, but we do create in the clone. You must be wondering that in Prototype Factory we show above, we are creating instances in the copy constructor. Isn’t that expensive. Yes, it is. But just think about HTTP request, its header consist version, encoding type, content type, server-type, etc. Initially, you need a find out these parameters using respective function calls. But once you got these, these are not going to change until connection closed. So there is no point in doing function calls to extract these params over & over. What cost us here is not parameters but their functions to extract value. Previously published at http://www.vishalchovatiya.com/prototype-design-pattern-in-modern-cpp/