将构造函数声明为私有显示错误。至少有一个公共构造函数是强制性的吗?

时间:2015-11-21 05:23:47

标签: c++ c++11 constructor destructor dynamic-memory-allocation

我是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;

}

对于上述程序,显示了两个错误。一个是在声明对象的main函数中;错误:内容中的错误。第二个是在调用构造函数的行中;错误:Book :: Book()是私有的。

主要不是直接访问代码中的构造函数。那为什么会显示访问错误?

3 个答案:

答案 0 :(得分:7)

不,public构造函数不是必需的。私有构造函数有用例。

  • 只有静态方法的类可能有private(或删除)构造函数,以防止实例被创建。
  • 单例类(其中只存在一个类的实例)可以通过使用private构造函数来强制执行其单例状态。该实例可以通过static getter。
  • 访问
  • 您可能希望遵循构建器或工厂模式,在此模式下,强制用户使用调用构造函数旁边的过程构造实例。该构建器或工厂将是该类的成员或friend,因此能够调用private构造函数。这种方案在Java中比C ++更常见,但C ++也允许它。

那就是说,你只是想构建一个类的实例:

Book book1;

这种用法肯定需要public默认构造函数。

答案 1 :(得分: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;

}

答案 2 :(得分:1)

完全没有!你不需要public constructor,但你需要一个工厂功能来创建该类的实例。在这种情况下,您需要使用关键字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

这里不需要公共控制人员。但是您需要make_X来创建类的实例。

您也可以使用friend代替静态。在这种情况下,代码将是: -

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

然后在类定义之外定义: -

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

它是如何运作的!干杯!!