一个关于 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 应如何解决。
...全文
79 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

69,382

社区成员

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

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