我有一个关于C++中私有构造函数的问题。如果构造函数是私有的,那么如何创建该类的实例?
我们是否需要在类内部添加getInstance()方法?
我有一个关于C++中私有构造函数的问题。如果构造函数是私有的,那么如何创建该类的实例?
我们是否需要在类内部添加getInstance()方法?
有几种情况需要使用 private
构造函数:
Restricting object creation for all but friend
s; in this case all constructors have to be 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`
};
Restricting certain type of constructor (i.e. copy constructor, default constructor). e.g. std::fstream
doesn't allow copying by such inaccessible constructor
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
};
To have a common delegate constructor, which is not supposed to be exposed to the outer world:
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()) {}
};
For singleton patterns when the singleton class
is not inheritible (if it's inheritible then use a protected
constructor)
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 created\n";
}
public:
};
int main()
{
aTestClass a;
aTestClass *anObject;
}
aTestClass a这行代码会导致错误,因为它间接地尝试访问私有构造函数。注释掉此行并运行程序,程序将完全正常运行。现在的问题是如何在这种情况下创建对象。让我们写另一个程序。
#include <iostream>
using namespace std;
class aTestClass
{
aTestClass() ////////// Private constructor of this class
{
cout << "Object created\n";
}
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
我们已经创建了一个包含私有构造函数的类的对象。
使用这个概念来实现单例模式。
如果某个构造函数是私有的,那么意味着只有该类本身(和友元)才能使用该构造函数创建实例。因此,您可以提供像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;
}
#include <optional>
class Object {
private:
Object(...) { /* ... */ }
friend std::optional<Object> make_object(...);
};
std::optional<Object> make_object(...)
{
// ...
if (error)
return std::nullopt;
// else
return std::make_optional<Object>(...);
}
然后像这样使用它:
bool f()
{
auto opt_obj = make_object(...);
if (!opt_obj)
return false;
// else
auto obj = *std::move(opt_obj); // API magic
// ...
return true;
}
C++中的私有构造函数可用于限制常量结构的对象创建。您可以在同一作用域内定义类似的常量,例如枚举:
struct MathConst{
static const uint8 ANG_180 = 180;
static const uint8 ANG_90 = 90;
private:
MathConst(); // Restricting object creation
};
像这样访问:MathConst::ANG_180
。
struct
,一切都会正常工作,并且更加简洁。 - Xeverous
getInstance()
方法来说,应该是static Singleton object
而不是Singleton object
。 - Peter