导航
  • 全部
  • 社区活动
  • 我有疑问
  • 博文收录
  • Ada助手
  • 问答
  • 架构师李肯带你学C语言
  • 花神庙码农的博客

一个关于 iostream 的问题, 请 C++ 专家们给我会诊!

yoyoyosiyu 2002-04-23 01:02:51
在我说明问题之前,请看程序:

#include <stdio.h>
#include <iostream>

using namespace std;

class clsTest
{
private:
char szTag;
public:
clsTest(char Tag):szTag(Tag)
{
cout << "class clsTest by Tag:" << szTag << " Constructor call" << endl;
};

~clsTest()
{
//printf("class clsTest by tag: %c Destructor call\n",szTag);
cout << "class clsTest by Tag:" << szTag << " Destructor call" << endl;
};
};

static clsTest a('A');

int main(int argc, char* argv[])
{
cout <<"inside main" << endl;

cout <<"leaving main" << endl;
return 0;
}

我认为输出结果是:

class clsTest by Tag:A Constructor call
inside main
leaving main
class clsTest by Tag:A Destructor call

但实际的输出是:
class clsTest by Tag:A Constructor call
inside main
leaving main

但如果将 clsTest 的析构函数的 cout 用法该为 printf ,就能得到我想要的结果,请问问题出在哪里?如果我在析构函数中仍然想用 cout 应如何解决。
...全文
给本帖投票
105 20 打赏 收藏 转发到动态 举报
写回复
用AI写文章
20 条回复
切换为时间正序
请发表友善的回复…
发表回复
Last_Dodo 2002-04-25
  • 打赏
  • 举报
回复
不知道什么原因我的回复不见了。

原因是a和cout的析构顺序。在UNIX上有可能让你保证你的顺序,但C++不能保证。这也是在C++中尽量避免使用全局变量的原因之一。

因为是global/static destructor调用你的destructor,所以你是抓不到那里的异常的。
yoyoyosiyu 2002-04-25
  • 打赏
  • 举报
回复
To All:
谢谢大家的帮助!分数有限,不能给每个人送分。
yoyoyosiyu 2002-04-25
  • 打赏
  • 举报
回复
To do_do:

谢谢,顺便问一下你,在哪里可以找到 global/static destructor 方面的资料。
北极猩猩 2002-04-24
  • 打赏
  • 举报
回复
在C++种static变量的初始化和析构顺序是不受保证的,因此,构造函数与析
构函数中的输出全有、有任何一个和全都没有都是符合C++标准的。(就是说
这问题,与编译器有关但不是编译器的bug)
如果初始化顺序真的很重要,需要其他的解决办法,比如说使用Singleton模
式,可以参考《设计模式》和《Effective C++》条款47。
yoyoyosiyu 2002-04-23
  • 打赏
  • 举报
回复
To mathe():
我觉得你说的有一定的道理,但有一点疑问,我知道 cout 也是一个 c++对象,但如果cout 的析构函数如果在 clsTest a 的函数之前被调用的话,那如果 clsTest 仍然使用 cout, 那程序应该产生一个例外(exception),就不单单是显示不出来结果。

To shanyourouqing(山有柔情):

你说得很对,但我的本意就是要声明一个可见范围在该编译单元的对象。而且观察他的工作情况
luoyiwen42 2002-04-23
  • 打赏
  • 举报
回复
请问各位大侠,“using namespace std;”有何用?
winnest 2002-04-23
  • 打赏
  • 举报
回复
Think In C++ 2nd里提到这个问题,即cout对象应该是个特殊对象,最后被析构,所以还是你的编译器有问题。
寂寞漂泊 2002-04-23
  • 打赏
  • 举报
回复
加了后生成的结果还是那个。。。
myan 2002-04-23
  • 打赏
  • 举报
回复
编译器提示你用/GX选项激活C++异常处理功能。
jime 2002-04-23
  • 打赏
  • 举报
回复
你们能不能写注释呀,我是个菜鸟,不看注释看不懂,谢谢!!!
寂寞漂泊 2002-04-23
  • 打赏
  • 举报
回复
在前面有警告的情况下生成的程序运行结果为
class clsTest by Tag:A Constructor call
inside main
leaving main
iostream与iostream.h到底有什么区别?
寂寞漂泊 2002-04-23
  • 打赏
  • 举报
回复
这是在VC命令行下得到的结果:
C:\Program Files\Microsoft Visual Studio\vc98\include\istream(547) : warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify -GX
C:\Program Files\Microsoft Visual Studio\vc98\include\ostream(234) : warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify -GX
C:\Program Files\Microsoft Visual Studio\vc98\include\ostream(229) : while compiling class-template member function 'class std::basic_ostream<char,struct std::char_traits<char> > &__thiscall std::basic_ostream<char,struct std::char_traits<char> >::put(char)'
C:\Program Files\Microsoft Visual Studio\vc98\include\ostream(234) : warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify -GX
C:\Program Files\Microsoft Visual Studio\vc98\include\ostream(229) : while compiling class-template member function 'class std::basic_ostream<unsigned short,struct std::char_traits<unsigned short> > &__thiscall std::basic_ostream<unsigned short,struct std::char_traits<unsigned short> >::put(unsigned short)'
C:\Program Files\Microsoft Visual Studio\vc98\include\istream(46) : warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify -GX
C:\Program Files\Microsoft Visual Studio\vc98\include\istream(41) : while compiling class-template member function 'bool __thiscall std::basic_istream<char,struct std::char_traits<char> >::ipfx(bool)'
C:\Program Files\Microsoft Visual Studio\vc98\include\istream(46) : warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify -GX
C:\Program Files\Microsoft Visual Studio\vc98\include\istream(41) : while compiling class-template member function 'bool __thiscall std::basic_istream<unsigned short,struct std::char_traits<unsigned short> >::ipfx(bool)'
C:\Program Files\Microsoft Visual Studio\vc98\include\xstring(525) : warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify -GX
C:\Program Files\Microsoft Visual Studio\vc98\include\xstring(521) : while compiling class-template member function 'void __thiscall std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >::_Copy(unsigned int)'
C:\Program Files\Microsoft Visual Studio\vc98\include\ostream(296) : warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify -GX
ios.cpp(13) : see reference to function template instantiation 'class std::basic_ostream<char,struct std::char_traits<char> > &__cdecl std::operator <<(class std::basic_ostream<char,struct std::char_traits<char> > &,const char *)' being compiled
C:\Program Files\Microsoft Visual Studio\vc98\include\ostream(325) : warning C4530: C++ exception handler used, but unwind semantics are not enabled. Specify -GX
ios.cpp(13) : see reference to function template instantiation 'class std::basic_ostream<char,struct std::char_traits<char> > &__cdecl std::operator <<(class std::basic_ostream<char,struct std::char_traits<char> > &,char)' being compiled
Microsoft (R) Incremental Linker Version 6.00.8168
Copyright (C) Microsoft Corp 1992-1998. All rights reserved.
如将iostream改为iostream.h去掉using namespacing std也可得到你想要的结果
大虾们解释一下
shanyourouqing 2002-04-23
  • 打赏
  • 举报
回复
对不想刚才漏掉一点;
至于原因我同意楼上的观点
把 static clsTest a('A');改为 clsTest a('A');
并放到main()里面即可得到你想要的结果:
int main(int argc, char* argv[])
{
clsTest a('A');
cout <<"inside main" << endl;

cout <<"leaving main" << endl;
return 0;
}
shanyourouqing 2002-04-23
  • 打赏
  • 举报
回复
把 static clsTest a('A');改为 clsTest a('A');
并放到main()里面即可得到你想要的结果:
int main(int argc, char* argv[])
{

cout <<"inside main" << endl;

cout <<"leaving main" << endl;
return 0;
}
mathe 2002-04-23
  • 打赏
  • 举报
回复
编译器也没有错,cout也是一个C++对象;所以如果cout的析构函数在clsTest A的析构函数之前调用,结果当然有问题了。
C++标准没有规定各全局变量析构函数调用的顺序,所以程序最终的行为无论是那一种,都没有错
liujuntao 2002-04-23
  • 打赏
  • 举报
回复
我用linux下的gcc编译器,得到正常结果!你的编译器有问题!
fangrk 2002-04-23
  • 打赏
  • 举报
回复
我用BCB4得到的:
class clsTest by Tag:A Constructor call
inside main
leaving main
class clsTest by Tag:A Destructor call

kinghawk 2002-04-23
  • 打赏
  • 举报
回复
程序没有问题,应该是编译器的原因!
Last_Dodo 2002-04-23
  • 打赏
  • 举报
回复
原因是cout在你的a之前被destruct掉。有的操作系统允许你设global的destruction顺序。
superzjx2000 2002-04-23
  • 打赏
  • 举报
回复
impossible

70,004

社区成员

发帖
与我相关
我的任务
社区描述
C语言相关问题讨论
社区管理员
  • C语言
  • 花神庙码农
  • 架构师李肯
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

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