C++两个单例互引用

冥辰mc 2017-12-04 05:31:44
忘了是不是Effective C++上看到的单例模式可以这样写:

static ClassName * instance()
{
static ClassName inst;
return &inst;
}

另外加上拷贝构造函数和赋值函数的私有声明,这里省略。
使用的时候
ClassName *p = ClassName::instance();
就行了。

我觉得很好理解,局部静态变量只会被初始化一次。
但是,世界上就是有但是存在,今天写代码遇到一个problem,如题所述:当两个单例类需要互相持有对方引用的时候,出现了一个搜索引擎上找不到答案的error:
terminate called after throwing an instance of '__gnu_cxx::recursive_init_error'
what(): std::exception


然后抱着怀疑的态度,写了个测试代码,报错一样,如下:


#pragma once
/*
* SingleA.h
* */
#include <iostream>
#include "SingleB.h"

class SingleB;

class SingleA
{
public:
static SingleA * instance()
{
static SingleA inst;
return &inst;
}

void print();
void callback();
private:
SingleB *_b;
SingleA();
SingleA(const SingleA&);
SingleA & operator= (const SingleA&);
};

#pragma once
/*
* SingleB.h
* */
#include <iostream>
#include "SingleA.h"

class SingleA;

class SingleB
{
public:
static SingleB * instance()
{
static SingleB inst;
return &inst;
}

void print();
private:
SingleA *_a;
SingleB();
SingleB(const SingleB&);
SingleB & operator= (const SingleB&);
};

/*
* SingleA.cpp
* */
#include "SingleA.h"

SingleA::SingleA()
{
_b = SingleB::instance();
}

void SingleA::print()
{
std::cout << "SingleA.print()" << std::endl;
_b->print();
}

void SingleA::callback()
{
std::cout << "SingleA.callback()" << std::endl;
}

/*
* SingleB.cpp
* */
#include "SingleB.h"

SingleB::SingleB()
{
_a = SingleA::instance();
}

void SingleB::print()
{
std::cout << "SingleB.print()" << std::endl;
_a->callback();
}

/*
* testSingleton.cpp
* */
#include "SingleA.h"
#include "SingleB.h"

int main()
{
SingleA *a = SingleA::instance();
a->print();
return 0;
}


Any suggestion? Thank you:)
...全文
386 8 打赏 收藏 转发到动态 举报
写回复
用AI写文章
8 条回复
切换为时间正序
请发表友善的回复…
发表回复
冥辰mc 2017-12-05
  • 打赏
  • 举报
回复
昨晚发现了 谢谢各位
真相重于对错 2017-12-05
  • 打赏
  • 举报
回复
引用 6 楼 zhao4zhong1 的回复:
[quote=引用 5 楼 hdt 的回复:] [quote=引用 4 楼 zhao4zhong1 的回复:] [quote=引用 3 楼 hdt 的回复:] 时间旅行者悖论, 你回到过去,把你祖父杀掉,会出现什么情况。 回到过去,时间旅行者和自己母亲结婚,会出现什么情况。
什么也不会发生。因为有很多个平行宇宙。[/quote] 嗯,对有这么个说法,[/quote] 没事到这里被科普漫画一下:http://blog.sina.com.cn/u/1736737707[/quote] 人生不过百,常怀千岁忧, 我这辈子估计看不到了
赵4老师 2017-12-05
  • 打赏
  • 举报
回复
引用 5 楼 hdt 的回复:
[quote=引用 4 楼 zhao4zhong1 的回复:] [quote=引用 3 楼 hdt 的回复:] 时间旅行者悖论, 你回到过去,把你祖父杀掉,会出现什么情况。 回到过去,时间旅行者和自己母亲结婚,会出现什么情况。
什么也不会发生。因为有很多个平行宇宙。[/quote] 嗯,对有这么个说法,[/quote] 没事到这里被科普漫画一下:http://blog.sina.com.cn/u/1736737707
真相重于对错 2017-12-05
  • 打赏
  • 举报
回复
引用 4 楼 zhao4zhong1 的回复:
[quote=引用 3 楼 hdt 的回复:] 时间旅行者悖论, 你回到过去,把你祖父杀掉,会出现什么情况。 回到过去,时间旅行者和自己母亲结婚,会出现什么情况。
什么也不会发生。因为有很多个平行宇宙。[/quote] 嗯,对有这么个说法,
赵4老师 2017-12-05
  • 打赏
  • 举报
回复
引用 3 楼 hdt 的回复:
时间旅行者悖论, 你回到过去,把你祖父杀掉,会出现什么情况。 回到过去,时间旅行者和自己母亲结婚,会出现什么情况。
什么也不会发生。因为有很多个平行宇宙。
真相重于对错 2017-12-04
  • 打赏
  • 举报
回复
时间旅行者悖论, 你回到过去,把你祖父杀掉,会出现什么情况。 回到过去,时间旅行者和自己母亲结婚,会出现什么情况。
  • 打赏
  • 举报
回复
构造函数里面应尽量少做工作,尤其是资源分配 一般这种问题加个init函数就可以了 SingleA::instance()->init(SingleB::instance()); SingleB::instance()->init(SingleA::instance()); SingleA::instance()->print();
paschen 版主 2017-12-04
  • 打赏
  • 举报
回复
你的代码实际会引发一个递归的构造初始化,因为你A在构造函数中(此时A对象还没构造完成)又去创建另一个B对象,而B在构造函数中(同样还没构造完成)又会去创建A(因为静态变量还没有初始过)。你可以把静态变量改为类的静态成员变量,这样变量的初始完成会提前

64,643

社区成员

发帖
与我相关
我的任务
社区描述
C++ 语言相关问题讨论,技术干货分享,前沿动态等
c++ 技术论坛(原bbs)
社区管理员
  • C++ 语言社区
  • encoderlee
  • paschen
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
  1. 请不要发布与C++技术无关的贴子
  2. 请不要发布与技术无关的招聘、广告的帖子
  3. 请尽可能的描述清楚你的问题,如果涉及到代码请尽可能的格式化一下

试试用AI创作助手写篇文章吧