使用共享指针访问单例子类时的SEGFAULT
SEGFAULT when accessing a singleton child class with shared pointer
我有一个模板类ISingleton
class ISingleton
{
public:
static T* getInstance()
{
lock_guard<mutex> guard(mMutex);
if (mInstance == NULL)
{
mInstance = new T();
}
return mInstance;
}
static void destroy()
{
lock_guard<mutex> guard(mMutex);
delete mInstance;
mInstance = NULL;
}
ISingleton(ISingleton const&) = delete;
ISingleton& operator =(ISingleton const&) = delete;
protected:
ISingleton()
{
}
virtual ~ISingleton()
{
}
private:
static T* mInstance;
static mutex mMutex;
};
CCD_ 2的父类和子类
class Parent
{
public:
Parent(string name) { mName = name; }
virtual ~Parent();
string getName(){ return mName; }
private:
string mName;
}
class Child : public Parent, public ISingleton<Child>
{
public:
virtual ~Child();
private:
Child() { mName = "child"; }
friend ISingleton<Child>;
};
我创建了一个指向像这样的单例的共享指针
void foo()
{
shared_ptr<Parent> module(Child::getInstance());
}
Parent *c = Child::getInstance();
c->getName(); //SEGFAULT
如果shared_ptr'
的引用计数达到零,就会出现问题。对Child::getName
的下一次调用将导致segfault。我不知道这是继承问题还是单例本身的实现问题。谢谢你的建议!
您所做的并不是C++中的单例。单例永远不会被破坏和重新创建,因此将其存储在智能指针中毫无意义。
但如果你想用智能指针销毁它,你需要告诉智能指针如何做。默认情况下,智能指针调用operator delete
。您可以在ISingleton
:中定义类特定的operator delete
void operator delete(void *me) noexcept
{
// Possibly assert(me == mInstance);
mInstance = nullptr;
::operator delete(me);
}
或者,您可以为智能指针提供一个lambda,它将调用destroy
而不是delete
:
std::shared_ptr<Parent> module(Child::getInstance(),
[](Parent*){ Child::destroy(); });
您不应该将singleton地址添加到智能指针中,因为它是拥有资源的singleton。
由于您需要一个非拥有shared_ptr
,您可以使用一个空的deleter:
std::shared_ptr<Parent> dummy_ptr(Child::getInstance(), [](Parent*){/*Nothing*/});
但将方法改为不服用CCD_ 11似乎更好。
相关文章:
- 继承期间显示未知行为的子类
- 通过指向指针数组的指针访问子类的属性
- 从父类方法返回子类对象
- c++, 在子类中,如何在没有对象的情况下访问父类的方法?
- 将父类对象强制转换为子类的问题
- 避免在C++中重复子类定义
- 将QOpenGLWidget子类转换为使用Metal而不是OpenGL的子类是否可行?
- 如何初始化矢量的模板化子类
- C++ 继承:将子类传递给需要基类的函数并获取子类行为
- 有没有办法按值将纯抽象类的所有子类传递给 C++ 中的函数?
- 使用子类覆盖基类中定义的函数
- 子类地址等于虚拟基类地址?
- 将子类方法声明为基类的友元
- C++子类共享变量?
- 如何检查模板专用化是否是基本模板的子类?
- 仅让特定类'Fabric'构造类'Foo'及其所有子类的实例
- 使用模板参数重载C++方法:如何使其适用于模板的子类?
- 基类中的默认析构函数禁用子类中的移动构造函数(如果有成员)
- 如何在C++子类中访问父类的私有变量
- 在构造子类对象的过程中,更改一个类属性的数据类型会导致segfault