全部
我正在使用C ++ 14,并且正在制作或多或少的标准Singleton。我正在使用最新的Visual Studio2017。此代码有效:
#include <memory>
class A
{
public:
static A& getInstance()
{
if (instance == nullptr)
instance = std::unique_ptr<A>(new A());
return *instance;
}
private:
A() {}
static std::unique_ptr<A> instance;
};
std::unique_ptr<A> A::instance = nullptr;
但是,当我将单例实例的创建更改为此时:
instance = std::make_unique<A>();
我收到一个尝试访问私有成员的编译错误:
Error C2248 'A::A': cannot access private member declared in class 'A'
c:\program files (x86)\microsoft visual studio\2017\professional\vc\tools\msvc\14.14.26428\include\memory 2510
这对我来说就像个错误,因为两种形式的功能应该相同?有想法吗?
答案 0 :(得分:3)
class MyClass {
private _myInstance: string;
private _myDomID: string;
private _myFunc = this.print.bind(this);
constructor(ID: string, domID: string) {
this._myInstance = ID;
this._myDomID = domID;
document.getElementById(domID).addEventListener('click', this._myFunc);
}
public print() {
console.log(this._myInstance);
}
public cleanUp() {
document.getElementById(this._myDomID).removeEventListener('click', this._myFunc);
}
的目的是控制所指向对象的生存期。您可以传递一个std::unique_ptr<>
,但这也将转移所指向对象的所有权。这个概念与单例概念不太匹配。只有一个地方可以创建(或删除)单例。您实际上并不需要std::unique_ptr<>
。正如评论中已经提到的那样,有更简单的方法。我希望使用@Praetorian的建议:
std::unique_ptr<>
之所以不能使用static A& getInstance()
{
static A instance;
return instance;
}
来实例化您的类,是因为构造函数是私有的。要访问它,您需要访问函数为std::make_unique<>()
。看看How to make std::make_unique a friend of my class。另一个解决方案是提供一个需要私有类型作为参数的公共构造函数,如int this solution所述。
答案 1 :(得分:3)
instance = std::make_unique<A>();
这将在函数A
中创建make_unique
。但是您要呼叫的ctor是私有的。
private:
struct ctor_permission_t{
explicit ctor_permission_t(int){};
};
public:
explicit A(ctor_permission_t):A(){}
};
然后
instance = std::make_unique<A>(ctor_permission_t{0});
ctor_permission_t
充当令牌,赋予其拥有者构造A
的权利。我们将此传递给make_unique
。
explicit int
中的ctor_permission_t
ctor使得无法在不命名类型的情况下创建它,并且仅在A
的实例和朋友中可以命名,因为它是私有的。这使得绕过此权限令牌很困难。