静态函数无法访问 C++ 单例私有构造函数
C++ Singleton private constructor not accessible from static function
我在这里有一个单例 class 声明:
#ifndef GLFW_CONTEXT_H
#define GLFW_CONTEXT_H
#include <memory>
class GLFWContextSingleton
{
public:
static std::shared_ptr<GLFWContextSingleton> GetInstance();
~GLFWContextSingleton();
GLFWContextSingleton(const GLFWContextSingleton& other) = delete;
GLFWContextSingleton* operator=(const GLFWContextSingleton* other) = delete;
private:
GLFWContextSingleton();
};
#endif
以及此处显示的 GetInstance
函数的实现
std::shared_ptr<GLFWContextSingleton> GLFWContextSingleton::GetInstance()
{
static std::weak_ptr<GLFWContextSingleton> weak_singleton_instance;
auto singleton_instance = weak_singleton_instance.lock();
if (singleton_instance == nullptr)
{
singleton_instance = std::make_shared<GLFWContextSingleton>();
weak_singleton_instance = singleton_instance;
}
return singleton_instance;
}
但是调用 std::make_shared<GLFWContextSingleton>()
给我一个错误提示
‘GLFWContextSingleton::GLFWContextSingleton()’ is private within this context
我认为这个静态方法可以访问私有成员函数。是什么原因造成的,我该如何解决?
静态函数确实可以访问私有成员。 make_shared
没有。
make_shared
是一个模板函数,它转发它得到的参数并调用指定class的构造函数。所以对默认构造函数的调用发生在 make_shared
函数内部,而不是在 GetInstance
函数内部,因此出现错误。
处理此问题的一种方法是使用私有嵌套 class 作为构造函数的唯一参数。
#include <memory>
class GLFWContextSingleton
{
private:
struct PrivateTag {};
public:
static std::shared_ptr<GLFWContextSingleton> GetInstance();
~GLFWContextSingleton();
GLFWContextSingleton(const GLFWContextSingleton& other) = delete;
GLFWContextSingleton* operator=(const GLFWContextSingleton* other) = delete;
GLFWContextSingleton(PrivateTag);
};
std::shared_ptr<GLFWContextSingleton> GLFWContextSingleton::GetInstance()
{
static std::weak_ptr<GLFWContextSingleton> weak_singleton_instance;
auto singleton_instance = weak_singleton_instance.lock();
if (singleton_instance == nullptr)
{
singleton_instance = std::make_shared<GLFWContextSingleton>(PrivateTag{});
weak_singleton_instance = singleton_instance;
}
return singleton_instance;
}
int main() {
}
这样我们保留构造函数 public,但为了使用它,我们需要一个 PrivateTag
,只有 class.
的成员可以访问
我在这里有一个单例 class 声明:
#ifndef GLFW_CONTEXT_H
#define GLFW_CONTEXT_H
#include <memory>
class GLFWContextSingleton
{
public:
static std::shared_ptr<GLFWContextSingleton> GetInstance();
~GLFWContextSingleton();
GLFWContextSingleton(const GLFWContextSingleton& other) = delete;
GLFWContextSingleton* operator=(const GLFWContextSingleton* other) = delete;
private:
GLFWContextSingleton();
};
#endif
以及此处显示的 GetInstance
函数的实现
std::shared_ptr<GLFWContextSingleton> GLFWContextSingleton::GetInstance()
{
static std::weak_ptr<GLFWContextSingleton> weak_singleton_instance;
auto singleton_instance = weak_singleton_instance.lock();
if (singleton_instance == nullptr)
{
singleton_instance = std::make_shared<GLFWContextSingleton>();
weak_singleton_instance = singleton_instance;
}
return singleton_instance;
}
但是调用 std::make_shared<GLFWContextSingleton>()
给我一个错误提示
‘GLFWContextSingleton::GLFWContextSingleton()’ is private within this context
我认为这个静态方法可以访问私有成员函数。是什么原因造成的,我该如何解决?
静态函数确实可以访问私有成员。 make_shared
没有。
make_shared
是一个模板函数,它转发它得到的参数并调用指定class的构造函数。所以对默认构造函数的调用发生在 make_shared
函数内部,而不是在 GetInstance
函数内部,因此出现错误。
处理此问题的一种方法是使用私有嵌套 class 作为构造函数的唯一参数。
#include <memory>
class GLFWContextSingleton
{
private:
struct PrivateTag {};
public:
static std::shared_ptr<GLFWContextSingleton> GetInstance();
~GLFWContextSingleton();
GLFWContextSingleton(const GLFWContextSingleton& other) = delete;
GLFWContextSingleton* operator=(const GLFWContextSingleton* other) = delete;
GLFWContextSingleton(PrivateTag);
};
std::shared_ptr<GLFWContextSingleton> GLFWContextSingleton::GetInstance()
{
static std::weak_ptr<GLFWContextSingleton> weak_singleton_instance;
auto singleton_instance = weak_singleton_instance.lock();
if (singleton_instance == nullptr)
{
singleton_instance = std::make_shared<GLFWContextSingleton>(PrivateTag{});
weak_singleton_instance = singleton_instance;
}
return singleton_instance;
}
int main() {
}
这样我们保留构造函数 public,但为了使用它,我们需要一个 PrivateTag
,只有 class.