3

Я ученик C++. Я составил следующую программу. Я работаю над концепцией конструкторов и деструкторов. У меня есть этот код ниже, где я объявляю частный деструктор и получаю доступ к закрытым членам, используя функцию-член класса из main(). Я знаю, что частный конструктор может быть объявлен, но также является публичным конструктором? вот мой код ниже:Объявление конструкторов как частных показывает ошибки. Обязателен ли хотя бы один публичный конструктор?

class Book 
{ 
private: 
    int *pages; 
    int *price; 


    Book()  //default constructor 
    { 
     pages = new int; 
     price = new int; 
     *pages = 300; 
     *price = 8; 
    } 

public: 
    void pre_destructor() 
    { 
     std::cout << "The pages:" << *pages << "\n"; 
     std::cout << "The price:" << *price << "\n"; 
    } 

~Book() //destructor 
    { 
     std::cout << "The pages:" << *pages << "\n"; 
     std::cout << "The price:" << *price << "\n"; 
     delete pages; 
     delete price; 
    } 

}; 

int main() 
{ 
    using namespace std; 
    Book book1; 

    cout << "Before using destructors" << endl; 
    cout << "---------------------------------"<< endl; 

    book1.pre_destructor(); 

    cout << "After using destructors" << endl; 
    cout << "---------------------------------"; 

    return 1; 

} 

Для вышеуказанной программы показаны две ошибки. Один из них находится в основной функции, где объявляется объект; Ошибка: ошибка в содержимом. Второй - в строке, где вызывается конструктор; Ошибка: Book :: Book() является закрытой.

Главное не имеет прямого доступа к конструктору в коде. Тогда почему это показывает ошибку доступа?

+1

Объявление конструктора как частного не позволит создать объект, в других областях. Поскольку конструктор не может быть вызван оттуда. поэтому конструктор/деструктор становится общедоступным! –

+2

Вам нужно получить [хорошую книгу] (http://stackoverflow.com/questions/388242/the-definitive-c-book-guide-and-list). –

+3

'Главное не имеет прямого доступа к конструктору в коде.' Это тоже. Строка 'Book book1;' инициализирует объект, используя свой конструктор по умолчанию (который вы сделали закрытым и, следовательно, недоступным). –

ответ

7

Нет, a public конструктор не является обязательным. Существуют частные случаи для частных конструкторов.

  • Класс, содержащий только статические методы, может содержать конструкторы private (или удаленные) для предотвращения создания экземпляров.
  • Одноэлементный класс (где существует только один экземпляр класса) может обеспечить его статус singleton с помощью конструктора private. К этому экземпляру можно получить доступ через getter static.
  • Возможно, вы захотите следовать за строителем или шаблоном фабрики, где вы вынуждаете своих пользователей создавать экземпляры, используя процесс, вызывающий конструктор. Этот строитель или фабрика будет либо членом класса, либо friend, поэтому он может вызвать конструктор private. Эта схема гораздо более распространена в Java, чем C++, но C++ также позволяет ее использовать.

Это говорит, что вы хотите просто построить экземпляр класса:

Book book1; 

Это использование определенно требует конструктор public по умолчанию.

+0

Это должно быть принято как ответ. хороший ответ. +1 – Destructor

2

Когда вы делаете конструктор закрытым, вам нужно выставить метод, чтобы внешние классы/методы могли создавать объект этого класса. Вы сделали бы это, создав статический метод, который, в свою очередь, создаст объект.

следующий код демонстрирует:

#include <iostream> 
class Book 
{ 
private: 
    int *pages; 
    int *price; 


    Book()  //default constructor 
    { 
     pages = new int(); 
     price = new int(); 
     *pages = 300; 
     *price = 8; 
    } 

public: 
    static Book* constructBook() 
    { 
     return new Book(); 
    } 

    void pre_destructor() 
    { 
     std::cout << "The pages:" << *pages << "\n"; 
     std::cout << "The price:" << *price << "\n"; 
    } 

    ~Book() //destructor 
    { 
     delete pages; 
     delete price; 
    } 

}; 

int main() 
{ 
    Book* book1 = Book::constructBook(); 

    std::cout << "Before using destructors" << endl; 
    std::cout << "---------------------------------"<< endl; 

    book1->pre_destructor(); 

    cout << "After using destructors" << endl; 
    cout << "---------------------------------"; 
    delete book1; 
    return 0; 

} 
1

Вовсе нет! Вам не нужен public constructor, но вам нужен фабричный fuction, чтобы создать экземпляр этого класса &. В этом случае вам нужно квалифицировать эту функцию с помощью ключевого слова static. Смотрите ниже: -

#include <iostream> 
using namespace std; 
class X 
{ 
    int x; 
    X(int x) 
    { 
     cout<<"creation\n"; 
     this->x = x; 
    } 
    public: 
    static X make_X (int x) // without static error message will be : error: cannot call member function 'X X::make_X(int)' without object 
    { 
     return X(x); 
    } 
    int& getx() 
    { 
     return x; 
    } 
    ~X() 
    { 
     cout<<"destruction\n"; 
    } 
}; 
int main() 
{ 
    auto obj = X::make_X(5); 
    auto ano = X::make_X(7); 
    cout << obj.getx() << '\t' << ano.getx() << '\n'; 
    return 0; 
} 

Выход: -

creation 
creation 
5 7 
destruction 
destruction 

Там нет необходимости общественного contrcutor здесь. Но для создания экземпляра класса вам понадобилось make_X.

Вы можете также использовать friend вместо статического.В этом случае код будет: -

friend X make_X (int x); // declare a prototype in the class 

Затем определяют вне определения класса: -

X make_X (int x) 
{ 
    return X(x); 
} 

Вот как это работает! Ура !!

+0

Остановить использование #include . Это не стандартный C++. Он будет работать только в gcc-компиляторе и делает ваши программы не переносимыми. – Destructor

+1

@PravasiMeet m sry для этого, следовательно, я сделал изменения – CppNITR