我测试了来自C++17的两种类型的单例
第一是unique_ptr第二是shared_ptr
它们必须与私有构造函数和析构函数一起工作,因为没有人可以更改任何实例状态。
我最终成功地编写了unique_ptr版本,但是shrared没有完成。
shared_ptr版本出错
错误是‘Singleton2 2::~Singleton2 2()’在这个上下文中是私有的‘{_p->~_Up();}
我怎样才能让shared_ptr单身?
这是代码
class Singleton1
{
public:
static Singleton1& GetInstance()
{
if(!mFlag)
{
mFlag = true;
mSingle = std::make_unique<Singleton1>(Singleton1(1));
}
return *mSingle.get();
}
private:
friend std::unique_ptr<Singleton1>::deleter_type;
Singleton1(int n)
: mNum(n)
{
std::cout << "this is unique_ptr singleton" << std::endl;
}
~Singleton1() = default;
private:
const int mNum;
inline static bool mFlag;
inline static std::unique_ptr<Singleton1> mSingle;
};
class Singleton2
{
public:
static Singleton2& GetInstance()
{
if(!mFlag)
{
mFlag = true;
mSingle = std::make_shared<Singleton2>(Singleton2(1));
}
return *mSingle.get();
}
private:
Singleton2(int n)
: mNum(n)
{
std::cout << "this is shared_ptr singleton" << std::endl;
}
~Singleton2() = default;
private:
const int mNum;
inline static bool mFlag;
inline static std::shared_ptr<Singleton2> mSingle;
};
int main()
{
Singleton1& res = Singleton1::GetInstance();
Singleton2& res = Singleton2::GetInstance();
return 0;
}
发布于 2022-07-27 10:31:15
您可以使用自定义删除器并使该friend
of Singleton2
#include <memory>
#include <iostream>
class Singleton2
{
struct Deleter {
void operator()(Singleton2* ptr){ delete ptr;}
};
friend Deleter;
public:
static Singleton2& GetInstance()
{
if(!mFlag)
{
mFlag = true;
mSingle = std::shared_ptr<Singleton2>(new Singleton2(1),Deleter{});
}
return *mSingle.get();
}
private:
Singleton2(int n)
: mNum(n)
{
std::cout << "this is shared_ptr singleton" << std::endl;
}
~Singleton2() = default;
private:
const int mNum;
inline static bool mFlag;
inline static std::shared_ptr<Singleton2> mSingle;
};
int main()
{
//Singleton1& res = Singleton1::GetInstance();
Singleton2& res = Singleton2::GetInstance();
return 0;
}
但是,考虑将析构函数公之于众。当指针被包裹起来时,就不会有有人不小心破坏物体的危险。如果他们想故意这么做,他们会找到一种方法,不管析构函数是否是private
。private
并不是一种以各种可能的方式阻止某人访问该函数的方法。相反,这是一种毫不含糊地告知其他人,他们不应该使用这种方法的一种方式。而且,由于您没有将指针传递给调用方,所以当析构函数是公共的时,它们也必须“玩把戏”。
PS:我建议您使用Meyers,其中实例存储为函数本地static
变量。它是线程安全的,而您的GetInstance
不是。
https://stackoverflow.com/questions/73136044
复制相似问题