Частный конструктор

Возможный дубликат:
Какой смысл делать конструктор закрытым в классе?

Где нам нужен частный конструктор? Как мы можем создать экземпляр класса с закрытым конструктором?

7 ответов

Решение

Закрытый конструктор означает, что пользователь не может напрямую создать экземпляр класса. Вместо этого вы можете создавать объекты, используя что-то вроде идиома именованного конструктора, где у вас есть static функции класса, которые могут создавать и возвращать экземпляры класса.

Идиома Именованный Конструктор для более интуитивного использования класса. Пример, приведенный в FAQ по C++, предназначен для класса, который можно использовать для представления нескольких систем координат.

Это вытягивается прямо из ссылки. Это класс, представляющий точки в разных системах координат, но он может использоваться для представления как прямоугольных, так и полярных точек, поэтому, чтобы сделать его более интуитивно понятным для пользователя, используются разные функции для представления того, какую систему координат возвращает Point представляет собой.

 #include <cmath>               // To get std::sin() and std::cos()

 class Point {
 public:
   static Point rectangular(float x, float y);      // Rectangular coord's
   static Point polar(float radius, float angle);   // Polar coordinates
   // These static methods are the so-called "named constructors"
   ...
 private:
   Point(float x, float y);     // Rectangular coordinates
   float x_, y_;
 };

 inline Point::Point(float x, float y)
   : x_(x), y_(y) { }

 inline Point Point::rectangular(float x, float y)
 { return Point(x, y); }

 inline Point Point::polar(float radius, float angle)
 { return Point(radius*std::cos(angle), radius*std::sin(angle)); }

Было много других ответов, которые также соответствуют духу того, почему частные конструкторы когда-либо используются в C++ (среди них шаблон Singleton).

Еще одна вещь, которую вы можете сделать с этим, - предотвратить наследование вашего класса, поскольку производные классы не смогут получить доступ к конструктору вашего класса. Конечно, в этой ситуации вам все еще нужна функция, которая создает экземпляры класса.

Одно из распространенных применений - шаблон синглтона, где вы хотите, чтобы существовал только один экземпляр класса. В этом случае вы можете предоставить static метод, который делает экземпляр объекта. Таким образом, можно управлять количеством объектов, созданных для конкретного класса.

Закрытый конструктор полезен, когда вы не хотите, чтобы ваш класс создавался пользователем. Чтобы создать такие классы, вам нужно объявить статический метод, который выполняет 'new' и возвращает указатель.

Класс с закрытыми ctors не может быть помещен в контейнеры STL, поскольку они требуют копирования ctor.

Целесообразно сделать конструктор закрытым, если есть другие методы, которые могут создавать экземпляры. Очевидными примерами являются шаблоны Singleton (каждый вызов возвращает один и тот же экземпляр) и Factory (каждый вызов обычно создает новый экземпляр).

Это обычно, когда вы хотите реализовать синглтон. Класс может иметь статический "фабричный метод", который проверяет, был ли создан экземпляр класса, и вызывает конструктор, если это не так.

Одно из распространенных применений - для обходных классов template-typedef, таких как:

template <class TObj>
class MyLibrariesSmartPointer
{
  MyLibrariesSmartPointer();
  public:
    typedef smart_ptr<TObj> type;
};

Очевидно, что открытый не реализованный конструктор будет работать так же хорошо, но частный конструктор выдает ошибку времени компиляции вместо ошибки времени компоновки, если кто-либо пытается установить MyLibrariesSmartPointer<SomeType> вместо MyLibrariesSmartPointer<SomeType>::type, что желательно.

Например, вы можете вызвать приватный конструктор внутри класса-друга или функции-друга.

Шаблон Singleton обычно использует его, чтобы убедиться, что никто не создает больше экземпляров заданного типа.

Другие вопросы по тегам