Почему мы не можем создать объект, если конструктор находится в закрытом разделе? - PullRequest
1 голос
/ 22 апреля 2010

Я хочу знать, почему мы не можем создать объект, если конструктор находится в закрытом разделе. Я знаю, что если я сделаю метод статическим, я могу вызвать этот метод, используя

<classname> :: <methodname(...)>;

Но почему мы не можем создать объект - это то, чего я не понимаю.

Я также знаю, если мой метод не является статичным, тогда я также могу вызвать функцию следующим образом:

class A
{
     A();
     public:
        void fun1();
        void fun2();
        void fun3();
};


int main()
{
     A *obj =(A*)malloc(sizeof(A));
     //Here we can't use new A() because constructor is in private 
     //but we can use malloc with it, but it will not call the constructor
     //and hence it is harmful because object may not be in usable state.
     obj->fun1();
     obj->fun2();
     obj->fun3();
}

Итак, мой вопрос: почему мы не можем создать объект, когда конструктор является приватным?

Ответы [ 4 ]

9 голосов
/ 22 апреля 2010

Поскольку это не доступно для программы, это то, что означает частное.Если вы объявите функцию-член или переменную private, вы также не сможете получить к ним доступ.Создание частных конструкторов на самом деле является полезным методом в C ++, так как позволяет сказать, что только определенные классы могут создавать экземпляры типа.Например:

class A {
   A() {} // private ctor
   friend class B;
};

class B {
   public:
     A * MakeA() {
        return new A;
     }
};

Только B может создавать объекты A - это полезно при реализации фабричного шаблона.

2 голосов
/ 22 апреля 2010

Вы не можете создать экземпляр своего класса, потому что конструктор - private. private переменные и функции-члены не могут использоваться вне самого класса.

Если вы хотите создать экземпляр своего класса, у вас есть два варианта.

Вариант 1 - создать конструктор. Это именно то, что нужно делать в подавляющем большинстве случаев. Создание конструктора private является полезной техникой, но только при попытке достичь определенных целей.

Опция 2 - создать фабричный метод public static. Обычно вы делаете это, когда вариант 1 не является опцией.

class A
{
     A();
     public:
    static A* Create() { return new A; }
        void fun1();
        void fun2();
        void fun3();
};


int main()
{
     A *obj = A::Create();
     //Here we can't use new A() because constructor is in private 
     //but we can use malloc with it, but it will not call the constructor
     //and hence it is harmful because object may not be in usable state.
     obj->fun1();
     obj->fun2();
     obj->fun3();
}
2 голосов
/ 22 апреля 2010

Оператор "new" должен вызывать конструктор, поэтому, если конструктор является закрытым, вы не можете выполнить код "obj = new A", кроме как внутри функций-членов самого класса A.

Я бы предположил, что вы столкнулись с техникой, которая очень часто используется в Java (и да, я знаю, что вы пишете на C ++, но принцип тот же), когда разработчик класса хочет убедиться, что когда-либо будет существовать один и только один экземпляр этого класса (который называется «синглтон»). Чтобы достичь этого, ему нужно запретить другому коду создавать дополнительные экземпляры класса, используя new, и сделать конструктор закрытым - один из способов сделать это. Вот фрагмент кода Java, иллюстрирующий эту технику.

public class MySingleton {

  private MySingleton() {
      // Private constructor, to prevent instantiation using "new"
      // outside of this class.
  }

  public synchronized static MySingleton getInstance() {
    static MySingleton instance = null;

    if (instance == null) {
        // I can use new here because I'm inside the class.
        instance = new MySingleton();
    }
    return instance;
  }

}

Даже если вы не знаете Java, синтаксис достаточно похож на C ++, поэтому вы должны понимать, что делает этот код. Дело в том, что единственный способ получить ссылку на экземпляр класса MySingleton в другом месте кода - это вызвать статический член класса getInstance ().

  MySingleton obj = MySingleton.getInstance();
2 голосов
/ 22 апреля 2010

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

...