What is the use of making constructor private in a

2019-01-02 19:29发布

Why should we make the constructor private in class? As we always need the constructor to be public.

标签: oop
23条回答
谁念西风独自凉
2楼-- · 2019-01-02 20:08

Some reasons where you may need private constructor:

  1. The constructor can only be accessed from static factory method inside the class itself. Singleton can also belong to this category.
  2. A utility class, that only contains static methods.
查看更多
流年柔荑漫光年
3楼-- · 2019-01-02 20:10

By providing a private constructor you prevent class instances from being created in any place other than this very class. There are several use cases for providing such constructor.

A. Your class instances are created in a static method. The static method is then declared as public.

class MyClass()
{
private:
  MyClass() { }

public:
  static MyClass * CreateInstance() { return new MyClass(); }
};

B. Your class is a singleton. This means, not more than one instance of your class exists in the program.

class MyClass()
{
private:
  MyClass() { }

public:
  MyClass & Instance()
  {
    static MyClass * aGlobalInst = new MyClass();
    return *aGlobalInst;
  }
};

C. (Only applies to the upcoming C++0x standard) You have several constructors. Some of them are declared public, others private. For reducing code size, public constructors 'call' private constructors which in turn do all the work. Your public constructors are thus called delegating constructors:

class MyClass
{
public:
  MyClass() : MyClass(2010, 1, 1) { }

private:
  MyClass(int theYear, int theMonth, int theDay) { /* do real work */ }
};

D. You want to limit object copying (for example, because of using a shared resource):

class MyClass
{
  SharedResource * myResource;

private:
  MyClass(const MyClass & theOriginal) { }
};

E. Your class is a utility class. That means, it only contains static members. In this case, no object instance must ever be created in the program.

查看更多
荒废的爱情
4楼-- · 2019-01-02 20:11

There are some instances where you might not want to use a public constructor; for example if you want a singleton class.

If you are writing an assembly used by 3rd parties there could be a number of internal classes that you only want created by your assembly and not to be instantiated by users of your assembly.

查看更多
刘海飞了
5楼-- · 2019-01-02 20:12

To leave a "back door" that allows another friend class/function to construct an object in a way forbidden to the user. An example that comes to mind would be a container constructing an iterator (C++):

Iterator Container::begin() { return Iterator(this->beginPtr_); }
// Iterator(pointer_type p) constructor is private,
//     and Container is a friend of Iterator.
查看更多
还给你的自由
6楼-- · 2019-01-02 20:12

In addition to the better-known uses…

To implement the Method Object pattern, which I’d summarize as:

“Private constructor, public static method”
“Object for implementation, function for interface”

If you want to implement a function using an object, and the object is not useful outside of doing a one-off computation (by a method call), then you have a Throwaway Object. You can encapsulate the object creation and method call in a static method, preventing this common anti-pattern:

z = new A(x,y).call();

…replacing it with a (namespaced) function call:

z = A.f(x,y);

The caller never needs to know or care that you’re using an object internally, yielding a cleaner interface, and preventing garbage from the object hanging around or incorrect use of the object.

For example, if you want to break up a computation across methods foo, bar, and zork, for example to share state without having to pass many values in and out of functions, you could implement it as follows:

class A {
  public static Z f(x, y) {
    A a = new A(x, y);
    a.foo();
    a.bar();
    return a.zork();
  }

  private A(X x, Y y) { /* ... */ };
}

This Method Object pattern is given in Smalltalk Best Practice Patterns, Kent Beck, pages 34–37, where it is the last step of a refactoring pattern, ending:

  1. Replace the original method with one that creates an instance of the new class, constructed with the parameters and receiver of the original method, and invokes “compute”.

This differs significantly from the other examples here: the class is instantiable (unlike a utility class), but the instances are private (unlike factory methods, including singletons etc.), and can live on the stack, since they never escape.

This pattern is very useful in bottoms-up OOP, where objects are used to simplify low-level implementation, but are not necessarily exposed externally, and contrasts with the top-down OOP that is often presented and begins with high-level interfaces.

查看更多
一个人的天荒地老
7楼-- · 2019-01-02 20:17

You can have more than one constructor. C++ provides a default constructor and a default copy constructor if you don't provide one explicitly. Suppose you have a class that can only be constructed using some parameterized constructor. Maybe it initialized variables. If a user then uses this class without that constructor, they can cause no end of problems. A good general rule: If the default implementation is not valid, make both the default and copy constructor private and don't provide an implementation:

class C
{
public:
    C(int x);

private:
    C();
    C(const C &);
};

Use the compiler to prevent users from using the object with the default constructors that are not valid.

查看更多
登录 后发表回答