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

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, 为什么也能别调用呢?
...全文
195 3 打赏 收藏 转发到动态 举报
写回复
用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只不过是想不想让你的子类继承记得析构而已
和父类没关
《Linux多线程服务端编程:使用muduo C++网络库》主要讲述采用现代C++在x86-64 Linux上编写多线程TCP网络服务程序的主流常规技术,重点讲解一种适应性较强的多线程服务器的编程模型,即one loop per thread。 目 录 第1部分C++ 多线程系统编程 第1章线程安全的对象生命期管理3 1.1当析构函数遇到多线程. . . . . . . . . . . . . . . . .. . . . . . . . . . . 3 1.1.1线程安全的定义. . . . . . . . . . . . . . . . .. . . . . . . . . . . 4 1.1.2MutexLock 与MutexLockGuard. . . . . . . . . . . . . . . . . . . . 4 1.1.3一个线程安全的Counter 示例.. . . . . . . . . . . . . . . . . . . 4 1.2对象的创建很简单. . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . 5 1.3销毁太难. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . 7 1.3.1mutex 不是办法. . . . . . . . . . . . . . . . . . . .. . . . . . . . 7 1.3.2作为数据成员的mutex 不能保护析构.. . . . . . . . . . . . . . 8 1.4线程安全的Observer 有多难.. . . . . . . . . . . . . . . . . . . . . . . . 8 1.5原始指针有何不妥. . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . 11 1.6神器shared_ptr/weak_ptr . . . . . . . . . .. . . . . . . . . . . . . . . . 13 1.7插曲:系统地避免各种指针错误. . . . . . . . . . . . . . . . .. . . . . . 14 1.8应用到Observer 上.. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 1.9再论shared_ptr 的线程安全.. . . . . . . . . . . . . . . . . . . . . . . . 17 1.10shared_ptr 技术与陷阱. . . .. . . . . . . . . . . . . . . . . . . . . . . . 19 1.11对象池. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . . 21 1.11.1enable_shared_from_this . . . . . . . . . . . . . . . . . . . . . . 23 1.11.2弱回调. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . 24 1.12替代方案. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . . 26 1.13心得与小结. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . . 26 1.14Observer 之谬. . . .. . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28 第2章线程同步精要 2.1互斥器(mutex). . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32 2.1.1只使用非递归的mutex . . . . . . . . . . . . . .. . . . . . . . . . 33 2.1.2死锁. . . . . . . . . . . . . . . . . . . .. . . . . . . . . . . . . . 35 2.2条件变量(condition variable). . . . . . . . . .

64,648

社区成员

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

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