求解: 在这几种情况下, 析构函数被调用和不被调用的原因.

HoNooD 2009-11-09 05:44:04

#include <iostream>
using namespace std;

// --------------------------
// 1. 返回指针的单例实现
// --------------------------
class SingletonA
{
public:
static SingletonA* GetInstance();
// private:
~SingletonA(); // 有人把这个析构函数定义为private, 不知为什么?
private:
SingletonA();
static SingletonA* m_pInstance;
};

SingletonA::SingletonA()
{
cout << "SingletonA: Constructor.\r\n";
}

SingletonA::~SingletonA()
{
cout << "SingletonA: Destructor.\r\n";
delete m_pInstance;
}

SingletonA* SingletonA::m_pInstance = NULL;

SingletonA* SingletonA::GetInstance()
{
if (!m_pInstance)
{
m_pInstance = new SingletonA;
}
return m_pInstance;
}

// --------------------------
// 2. 返回引用的单例实现
// --------------------------
class SingletonB
{
public:
static SingletonB& GetInstance();
private:
SingletonB();
SingletonB(const SingletonB&);
SingletonB& operator=(const SingletonB&);
~SingletonB(); // 不知道为什么要把这个析构函数定义为private?
};

SingletonB::SingletonB()
{
cout << "SingletonB: Constructor.\r\n";
}

SingletonB::~SingletonB()
{
cout << "SingletonB: Destructor.\r\n";
}

SingletonB& SingletonB::GetInstance()
{
static SingletonB theSingleton;
return theSingleton;
}

// --------------------------
// 3. 随意定义了一个普通类
// --------------------------
class Foo
{
public:
Foo()
{
cout << "Foo: Constructor.\r\n";
}
// private:
~Foo() // 这个析构函数如果是private, 下面测试编译叫报错.
{
cout << "Foo: Destructor.\r\n";
}
};

// --------------------------
// 4. 测试
// --------------------------
int main()
{
SingletonA* instA = SingletonA::GetInstance();
SingletonB& instB = SingletonB::GetInstance();
Foo foo;

return 0;
}

// --------------------------
// 5. 控制台输出
// --------------------------
// SingletonA: Constructor.
// SingletonB: Constructor.
// Foo: Constructor.
// Foo: Destructor.
// SingletonB: Destructor.

// --------------------------
// 6. 我的问题
// --------------------------
// (1) 无论SingletonA的析构函数定义成private还是public, 为什么在上面的测试中都不会被调用?
// (2) 无论SingletonB的析构函数定义成private还是public, 为什么在上面的测试中都会被调用?
// (3) 写的Foo类是想测试通常情况下, 如果析构函数定义成private, 编译就不通过(提示无法调用私有
// 方法), 的确是那样. 那上面SingletonB的(析构函数)即使是private, 为什么也能别调用呢?
...全文
239 3 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
3 条回复
切换为时间正序
请发表友善的回复…
发表回复
AbnormalSubmarine 2009-11-10
  • 打赏
  • 举报
回复
1:private的定义你要弄清楚
只能在自己的成员中被访问!
因此,Foo的构造或者析构函数被声明称私有的话,是不能在Foo类的区域之外被访问的!
因此编译或出错!!
2:静态存变量或者对象只能存储在静态存储区,这个区域的生命周期随着进程的消亡而消亡!
因此,1楼的解释非常正确
HoNooD 2009-11-09
  • 打赏
  • 举报
回复
[Quote=引用 1 楼 forster 的回复:]
A你new了就调constructor没有delete当然不调destructor
B你那个静态的对象在第一次调用GetInstance()创建(constructor),进程结束时释放(destructor)
foo典型的局部变量作用域结束destructor
所以这个顺序
// Foo: Destructor.
// SingletonB: Destructor.
你可以
  SingletonA* instA = SingletonA::GetInstance();
  SingletonB& instB = SingletonB::GetInstance();
              instB = SingletonB::GetInstance();
  Foo foo;
结果应该一样

生命private还是public只不过是想不想让你的子类继承记得析构而已
和父类没关

[/Quote]

你讲的析构函数调用时刻学习了.
但访问权限的还是不理解, 这几个类都没有被继承的意思. SingletonB的声明为private依然能被调用, Foo的为什么不行?
forster 2009-11-09
  • 打赏
  • 举报
回复
A你new了就调constructor没有delete当然不调destructor
B你那个静态的对象在第一次调用GetInstance()创建(constructor),进程结束时释放(destructor)
foo典型的局部变量作用域结束destructor
所以这个顺序
// Foo: Destructor.
// SingletonB: Destructor.
你可以
SingletonA* instA = SingletonA::GetInstance();
SingletonB& instB = SingletonB::GetInstance();
instB = SingletonB::GetInstance();
Foo foo;
结果应该一样

生命private还是public只不过是想不想让你的子类继承记得析构而已
和父类没关

65,186

社区成员

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

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