When do we need a private constructor in C++?

I have a question about private constructors in C++. If the constructor is private, how can I create an instance of the class?

Should we have a getInstance() method inside the class?


Solution 1:

There are a few scenarios for having private constructors:

  1. Restricting object creation for all but friends; in this case all constructors have to be private

    class A
    {
    private:
       A () {}
    public:
       // other accessible methods
       friend class B;
    };
    
    class B
    {
    public:
       A* Create_A () { return new A; }  // creation rights only with `B`
    };
    
  2. Restricting certain type of constructor (i.e. copy constructor, default constructor). e.g. std::fstream doesn't allow copying by such inaccessible constructor

    class A
    {
    public:
       A();
       A(int);
    private:
       A(const A&);  // C++03: Even `friend`s can't use this
       A(const A&) = delete;  // C++11: making `private` doesn't matter
    };
    
  3. To have a common delegate constructor, which is not supposed to be exposed to the outer world:

    class A
    {
    private: 
      int x_;
      A (const int x) : x_(x) {} // common delegate; but within limits of `A`
    public:
      A (const B& b) : A(b.x_) {}
      A (const C& c) : A(c.foo()) {}
    };
    
  4. For singleton patterns when the singleton class is not inheritible (if it's inheritible then use a protected constructor)

    class Singleton
    {
    public:
       static Singleton& getInstance() {
          Singleton object; // lazy initialization or use `new` & null-check
          return object;
       }
    private:
       Singleton() {}  // make `protected` for further inheritance
       Singleton(const Singleton&);  // inaccessible
       Singleton& operator=(const Singleton&);  // inaccessible
    };
    

Solution 2:

A private constructor is commonly used with Builder methods, for example in the Named Constructor idiom.

class Point
{
public:
  static Point Polar(double, double);
  static Point Cartesian(double, double);
private:
  Point(double,double);
};

In this (typical) example, the Named Constructor idiom is used to make it explicitly which coordinate system is used to build the Point object.