我们什么时候需要C++中的私有构造函数

When do we need a private constructor in C++?

本文关键字:构造函数 C++ 什么时候 我们      更新时间:2023-10-16

我有一个关于C++中私有构造函数的问题。如果构造函数是私有的,我如何创建类的实例?

我们应该在类中有一个getInstance((方法吗?

有几个private构造函数的场景:

  1. 限制除friend以外的所有对象的创建;在这种情况下,所有构造函数都必须是private

    class A
    {
    private:
       A () {}
    public:
       // other accessible methods
       friend class B;
    };
    class B
    {
    public:
       A* Create_A () { return new A; }  // creation rights only with `B`
    };
    
  2. 限制特定类型的构造函数(即复制构造函数、默认构造函数(。例如std::fstream不允许通过这种不可访问的构造函数进行复制

    class A
    {
    public:
       A();
       A(int);
    private:
       A(const A&);  // C++03: Even `friend`s can't use this
       A(const A&) = delete;  // C++11: making `private` doesn't matter
    };
    
  3. 有一个通用的委托构造函数,它不应该暴露在外部世界:

    class A
    {
    private: 
      int x_;
      A (const int x) : x_(x) {} // common delegate; but within limits of `A`
    public:
      A (const B& b) : A(b.x_) {}
      A (const C& c) : A(c.foo()) {}
    };
    
  4. 对于单例模式,当单例class不可继承时(如果它是可继承的,则使用protected构造函数(

    class Singleton
    {
    public:
       static Singleton& getInstance() {
          Singleton object; // lazy initialization or use `new` & null-check
          return object;
       }
    private:
       Singleton() {}  // make `protected` for further inheritance
       Singleton(const Singleton&);  // inaccessible
       Singleton& operator=(const Singleton&);  // inaccessible
    };
    

私有构造函数通常与Builder方法一起使用,例如在命名构造函数习惯用法中。

class Point
{
public:
  static Point Polar(double, double);
  static Point Cartesian(double, double);
private:
  Point(double,double);
};

在这个(典型的(示例中,命名构造函数习惯用法用于明确地确定使用哪个坐标系来构建Point对象。

当您想要控制类的对象创建时,私有构造函数非常有用。

让我们试试代码:

#include <iostream>
using namespace std;
class aTestClass
{
    aTestClass() ////////// Private constructor of this class
    {
        cout << "Object createdn";
    }
    public:
};
int main()
{
    aTestClass a;
    aTestClass *anObject;
}

aTestClass a行导致错误,因为该行正在间接尝试访问私有构造函数。注释掉这一行并运行程序。它运行得非常好。现在的问题是如何在这种情况下创建对象。让我们再写一个程序。

#include <iostream>
using namespace std;
class aTestClass
{
    aTestClass() ////////// Private constructor of this class
    {
        cout << "Object createdn";
    }
    public:
    aTestClass* getAnObject() ///// A public method create an object of this class and return the address of an object of that class
    {
        return (new aTestClass);
    }
};
int main()
{
    //aTestClass a;
    aTestClass *anObject = NULL;
    anObject = anObject->getAnObject();
}

输出为

Object created

因此,我们创建了一个包含私有构造函数的类的对象。

使用此概念来实现单例类

是的,这通常用于通过静态成员函数访问对象的Singleton模式。

如果某个构造函数是私有的,这意味着除了类本身(和朋友(之外,任何人都不能使用该构造函数创建它的实例。因此,您可以提供像getInstance((这样的静态方法来创建类的实例,或者在一些朋友类/方法中创建实例。

这取决于构造函数最初被设置为私有的原因(您应该询问编写您正在编辑的类的人(。有时,构造函数可能被设置为私有,以禁止复制构造(同时允许通过其他构造函数进行构造(。其他时候,构造函数可能被设置为私有的,以禁止创建类,除非是由类的"朋友"创建(如果类是一个"助手",则通常会这样做,该"助手"只能由创建助手类的类使用(。构造函数也可以是私有的,以强制使用(通常是静态的(创建函数。

如果创建私有构造函数,则需要在类中创建对象

#include<iostream>
//factory method
using namespace std;
class Test
{
 private:
 Test(){
 cout<<"Object created"<<endl;
}
public:
    static Test* m1(){
        Test *t = new Test();
        return t;
    }
    void m2(){
        cout<<"m2-Test"<<endl;
    }
};
int main(){
 Test *t = Test::m1();
 t->m2();
 return 0;
}

C++中的私有构造函数可用于限制常量结构的对象创建。您可以在相同的范围内定义类似的常量,如enum:

struct MathConst{
    static const uint8 ANG_180 = 180;
    static const uint8 ANG_90  = 90;
    private:
        MathConst(); // Restricting object creation
};

MathConst::ANG_180一样访问它。