Implementing Sample Abstract Factory Pattern using Smart Pointers in C++ Was trying to implement and example code to smart pointer from link.
Is it a good practice? To go with all unique pointers or should we use shared pointers in this case? How can i improve this ?

#include &lt;iostream&gt;
#include &lt;string&gt;
#include&lt;memory&gt;

void LOG(std::string strText)
{
    std::cout &lt;&lt; strText &lt;&lt; std::endl;
}

class Widget {
public:
    virtual void draw() = 0;
};

class WindowsBtn : public Widget
{
public:
    void draw() {
        LOG("Windows Button");
    }
};

class WindowsMenu : public Widget
{
public:
    void draw() {
        LOG("Windows Menu");
    }
};

class LinuxBtn : public Widget
{
public:
    void draw() {
        LOG("Linux Button");
    }
};

class LinuxMenu : public Widget
{
public:
    void draw() {
        LOG("Linux Menu");
    }
};
/*
class WidgetFactory
{
public:
    virtual Widget* CreateButton() = 0;
    virtual Widget* CreateMenu() = 0;
};

class WindowsFactory : public WidgetFactory{
public:
    Widget* CreateButton() {
        return (new WindowsBtn);
    }

    Widget* CreateMenu() {
        return (new WindowsMenu);
    }

};

class LinuxFactory : public WidgetFactory{
public:
    Widget* CreateButton() {
        return (new LinuxBtn);
    }

    Widget* CreateMenu() {
        return (new LinuxMenu);
    }

};

class Client
{
    WidgetFactory * factory;
public:
    Client(WidgetFactory* factory) :factory(factory)
    {}

    void draw(){
        Widget * wd = factory-&gt;CreateButton();
        wd-&gt;draw();
        display1();
        display2();
    }
    void display1()
    {
        Widget * w[] = {
            factory-&gt;CreateButton(),
            factory-&gt;CreateMenu()
        };
        w[0]-&gt;draw();
        w[1]-&gt;draw();
    }
    void display2()
    {
        Widget * w[] = {
            factory-&gt;CreateMenu(),
            factory-&gt;CreateButton()
        };
        w[0]-&gt;draw();
        w[1]-&gt;draw();
    }

};
*/
class SmartWidgetFactory
{
public:
    virtual std::unique_ptr&lt;Widget&gt; CreateButton() = 0;
    virtual std::unique_ptr&lt;Widget&gt; CreateMenu() = 0;
};

class SmartWindowsFactory : public SmartWidgetFactory {
public:
    std::unique_ptr&lt;Widget&gt; CreateButton() {
        return std::make_unique&lt;WindowsBtn&gt;();
    }

    std::unique_ptr&lt;Widget&gt; CreateMenu() {
        return  std::make_unique&lt;WindowsMenu&gt;();
    }
};

class SmartLinuxFactory : public SmartWidgetFactory {
public:
    std::unique_ptr&lt;Widget&gt; CreateButton() {
        return  std::make_unique&lt;LinuxBtn&gt;();
    }

    std::unique_ptr&lt;Widget&gt; CreateMenu() {
        return std::make_unique&lt;LinuxMenu&gt;();
    }
};

class SmartClient
{
    std::unique_ptr&lt;SmartWidgetFactory&gt; factory;
public:
    SmartClient(std::unique_ptr&lt;SmartWidgetFactory&gt; oFactory)
    {
        factory = std::move(oFactory);
    }

    void draw() {
        std::unique_ptr&lt;Widget&gt; wd = factory-&gt;CreateButton();
        wd-&gt;draw();
        display1();
        display2();
    }
    void display1()
    {
        std::unique_ptr&lt;Widget&gt; w[] = {
            factory-&gt;CreateButton(),
            factory-&gt;CreateMenu()
        };
        w[0]-&gt;draw();
        w[1]-&gt;draw();
    }
    void display2()
    {
        std::unique_ptr&lt;Widget&gt; w[] = {
            factory-&gt;CreateMenu(),
            factory-&gt;CreateButton()
        };
        w[0]-&gt;draw();
        w[1]-&gt;draw();
    }
};

int _tmain(int argc, _TCHAR* argv[])
{

    /*WidgetFactory *factory;
    factory = new LinuxFactory;
    Client *c = new Client(factory);
    c-&gt;draw();*/

    std::unique_ptr&lt; SmartWidgetFactory &gt; oFactory = std::make_unique&lt;SmartLinuxFactory&gt;();
    std::unique_ptr&lt;SmartClient&gt; oClient = std::make_unique&lt;SmartClient&gt;( std::move(oFactory) );
    oClient-&gt;draw();

    return 0;
}
First, the big bug.  Your Widget class has no virtual destructor! This means that every time you return a unique_ptr&lt;Widget&gt;, you're losing the information about what kind of widget needs destroying.

Clang will actually diagnose this mistake for you. No matter what compiler you use, make sure you turn on warnings via -Wall -Wextra (or -W4 on MSVC).



int _tmain(int argc, _TCHAR* argv[])


This is a non-standard main routine. Maybe I'm a POSIX chauvinist, but at least for posting publicly, I'd think it would be more appropriate to use

int main(int, char **)


or even better,

int main()


(since you don't use either of those parameters for anything).

Also notice that I'm using char** instead of char*[], because in C and C++, a function parameter cannot be an array. It is pointless to deceive yourself and mean to deceive others.



SmartClient(std::unique_ptr&lt;SmartWidgetFactory&gt; oFactory)


This constructor should be marked explicit. In fact, every constructor you ever write (except for copy constructors and move constructors) should be explicit. If you leave off the explicit, then you're enabling people to write code like

std::unique_ptr&lt;SmartWidgetFactory&gt; pf = ...;
SmartClient sc = std::move(pf);


or even

SmartClient sc = nullptr;


and it'll compile, and they won't realize what they did wrong until runtime. It's better to catch this kind of thing at compile time. Mark all your constructors explicit.



std::unique_ptr&lt;Widget&gt; CreateButton()


If you intended this function to override the virtual function in the base class, you should have marked it override. (It may still override the virtual function in the base class, even without override, if you spelled everything correctly; but don't bet your workday on it. Mark all overriding functions override and catch your bugs at compile time.)

Also, consider whether it makes conceptual sense that "creating a button" is a non-const method of the factory. Maybe it does; I tend to think it doesn't. So I would write this as

std::unique_ptr&lt;Widget&gt; CreateButton() const override




std::unique_ptr&lt;SmartClient&gt; oClient = std::make_unique&lt;SmartClient&gt;( std::move(oFactory) );


Why does this need to be heap-allocated?

auto oClient = SmartClient(std::move(oFactory));


Even if you want to keep using make_unique for some reason, consider replacing the cumbersome type name std::unique_ptr&lt;SmartClient&gt; with auto:

auto oClient = std::make_unique&lt;SmartClient&gt;(std::move(oFactory));


Notice I've also normalized the whitespace while I'm at it.



void LOG(std::string strText)


Pass large expensive-to-copy objects, such as std::string, by const reference.

void LOG(const std::string&amp; text)


If you are on C++17, consider replacing const std::string&amp; parameters with std::string_view parameters:

void LOG(std::string_view text)


Be aware that you should use string_view only in places where it would make equal sense to use a reference type (so, parameters, and that's it).

Also be aware that when people see LOG("foo") in your code, they will assume that LOG is a macro, because it's ALL UPPER CASE. If you mean for people to assume it's a function, call it print_to_log or something like that.