Я всегда читал, что приватный конструктор предотвращает создание объектов.
Я использовал их в одноэлементных шаблонах, и я знаю, как создавать объекты, используя приватный конструктор (используя статические методы и т. Д.).
Я знаю, что конструкторы используются для инициализации объектов.
Но я не совсем понимаю, что заставляет частные конструкторы предотвращать создание объектов.
Что делать, если мой объект не получает инициализации. Я имею в виду, что это должно выбрасывать мусор, но почему это ограничивает ??
Я проверил все существующие ответы в stackoverflow, но я не понимаю точную концепцию.
Чтобы создать объект в C ++, необходимо вызвать конструктор. Если конструктор, который должен быть вызван, недоступен, то он не может быть вызван и объект не может быть создан.
Точка private
конструктор не предотвращение строительство объекта. Речь идет о контроле того, какой код может получить доступ к конструктору, и, следовательно, ограничении того, какой код создает объект, который является экземпляром этого класса. private
конструктор доступен для всех функций-членов (static
или иным образом) класса и всем заявленным friend
класса (которые могут быть отдельными функциями или другими классами), поэтому любой из них может создать экземпляр класса, используя private
конструктор (при условии, что конструктор определен).
Если конструктор не может быть вызван, объект не может быть инициализирован. В конце концов, работа конструктора заключается в инициализации объекта. Но если конструктор недоступен, тогда объект не может быть создан, поэтому невозможно иметь неинициализированный объект.
Конечно, ничто не мешает классу иметь несколько конструкторов с разными элементами управления доступом (private
, protected
, а также public
). class
с public
конструктор может быть создан с использованием этого конструктора любым кодом. Но любая попытка использовать private
конструктор (не являющийся членомfriend
) все равно будет отклонено. Таким образом, контроль доступа позволяет (разработчик) class
некоторая мера контроля над тем, как создается экземпляр.
Не определяя (т.е. не реализуя) конструктор, препятствует созданию объекта. Если этот конструктор private
компилятор отклонит попытку его вызова (если только функция, пытающаяся создать экземпляр, не является членом или friend
, как указано выше). Для членов и друзей класса компилятор разрешит доступ к конструктору, но (в типичной цепочке инструментов compile-затем-link) компоновщик не будет создавать исполняемый файл, так как он не может разрешить вызов функции, которая не определена , Используя технику маркировки конструктора private
и не определять его — это распространенный способ предотвращения создания экземпляром класса кода (либо предотвращая компиляцию кода, либо предотвращая его запуск).
Неверно говорить, что пометка частного конструктора предотвращать создание объекта. Все это делает ограничение создание объекта в вашем коде внутри класса только с закрытыми конструкторами. Вы можете создать новый объект, в то время как другие не могут.
Это хорошо работает для синглетонов, потому что помогает вам гарантировать, что ваш синглтон остается единственным экземпляром класса.
Закрытая область видимости класса не предотвращает создание экземпляров класса, но фактически ограничивает «кто» может создавать объект.
это похоже на другие данные члена, находящиеся в частном доступе, к которым нельзя получить доступ извне, но только для accessors
а также getters
и другие `дружественные функции и классы:
#include <iostream>
using namespace std;
class Foo
{
public:
Foo(int x) : value(x){ cout << "Foo(int) public ctor" << endl;} // ctor
void SetValue(int x) {value = x;} // setter
int GetValue()const{return value;}// getter
private:
int value;
Foo(){ cout << "Foo() private ctor" << endl;} // private ctor
friend ostream& operator<<(ostream& out, Foo& rhs)
{
out << rhs.value;
return out;
}
friend Foo* CreateObject();
};
Foo* CreateObject()
{
Foo* ptrFoo = new Foo;
return ptrFoo;
}int main ()
{
//Foo theFoo; // error C2248: 'Foo::Foo' : cannot access private member declared in class 'Foo'
Foo theFoo2(0); // ok
// cout << theFoo2.value << endl; // error C2248: 'value' : cannot access private member declared in class 'Foo'
cout << theFoo2.GetValue() << endl; // ok
cout << theFoo2 << endl;
Foo* ptrFoo = CreateObject();
ptrFoo->SetValue(7);
cout << ptrFoo->GetValue() << endl;cout << endl;
return 0;
}
C ++ не позволяет создавать объекты без вызова конструктора. И если конструктор недоступен, создание не может быть завершено. Время жизни объекта определенный быть между вызовами конструктора и деструктора.
Конечно, вы можете выделить необработанную память и просто привести ее к указателю на тип объекта (как это сделано в C
), но у вас не будет объекта этого класса. Пока конструктор не вызывается для превращения необработанной области памяти в представление объекта, эта область памяти формально не содержит объекта.
Поскольку вы не можете вызывать метод закрытого класса извне класса, а если конструктор является закрытым, это означает, что вы не можете создать экземпляр класса, поскольку создание объекта требует, чтобы конструктор был вызван.
Конструктор в этом отношении ничем не отличается от любого другого метода класса. Если метод класса является закрытым, вы уже понимаете, что не можете вызывать его извне класса. И так как конструктор должен быть вызван для создания экземпляра класса с закрытым конструктором.