user267885
user267885

Reputation:

Prevent instantiation of an object outside its factory method

Suppose I have a class with a factory method

class A {
public:
  static A* newA()
  {
    // Some code, logging, ...
    return new A();
  }
}

Is it possible to prevent the instantiation of an object of this class with a new, so that factory method is the only method to create an instance of the object?

Upvotes: 5

Views: 2767

Answers (2)

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272517

Sure; just make the constructor private (protected if this is a base class):

class A {
public:
  static A* newA()
  {
    // Some code, logging, ...
    return new A();
  }

private:
  A() {}  // Default constructor
};

You should make the copy constructor private/protected as well, if required.

And as always, you should strongly consider returning a smart pointer rather than a raw pointer, in order to simplify memory management issues.

Upvotes: 8

AJG85
AJG85

Reputation: 16197

You may also want to make the copy constructor private as well or with new C++11 syntax you can explicitly tell the compiler to not copy it and make the default constructor private with something like this:

struct NonCopyable {
    NonCopyable & operator=(const NonCopyable&) = delete;
    NonCopyable(const NonCopyable&) = delete;
    NonCopyable() = default;
};

class A : NonCopyable {
public:
  static std::shared_ptr<A> newA()
  {
    // Some code, logging, ...
    return std::make_shared<A>();
  }

private:
  A() {}  // Default constructor
};

The C++03 way was usually something like this:

class A {
public:
  static A* newA()
  {
    // Some code, logging, ...
    return new A();
  }

private:
  A() {}                        // no outsider default constructor
  A(const A& rhs);              // no copy
  A& operator=(const A& rhs);   // no assignment
};

int main()
{
    A x;        // C2248
    A y(x);     // C2248
    x = y;      // C2248
    A* p = A::newA(); // OK
    std::cin.get();
    return 0;
}

Upvotes: 3

Related Questions