【问题标题】:C++ Destructor ExceptionC++ 析构函数异常
【发布时间】:2011-05-11 11:21:20
【问题描述】:

我是一名新手程序员,正在为学校编写一些代码。执行以下代码时,会输出 BAD 字样。我不明白为什么WriteLettersObj对象终止时析构函数中的字母C没有输出。

// Lab 1 
//
#include "stdafx.h"
#include <iostream>
#include <conio.h>
using namespace std;

class WriteLetters {
public:
    WriteLetters();
    void writeOneLetter();
    ~WriteLetters();
} WriteLettersObj;

WriteLetters::WriteLetters() {
    cout << "B";
}

void WriteLetters::writeOneLetter() {
    cout << "A";
}

WriteLetters::~WriteLetters() {
    cout << "C" << endl;
}

int main() {
    WriteLettersObj.writeOneLetter();
    cout << "D";
    getch();

    return 0;
}

【问题讨论】:

  • 如果你删除 getch() 会打印出 BADC 吗?我在 Unix 上运行 g++ 删除了 getch() 和 stdafx/conio.h 标头,它打印出 BADC。
  • 我在没有getch()的情况下试过了,确实如此
  • 即使getch() 也可以,唯一的问题是他的屏幕在他看到输出之前就消失了。看看我下面的答案。
  • 您确定结果吗? std::cout 不会被破坏,所以C 肯定应该被打印出来。 (你为什么打电话给getch()?这似乎没有任何意义。)
  • @James McNellis - 在 Visual C++ 2010 中,输出窗口关闭,我们实际上应该在最后的 return 语句处设置断点。一旦我们在这个断点之后继续,输出窗口 get 关闭并且析构函数调用 cout 语句不可见。我的意思是说,尽管实际调用了析构函数,但输出窗口会立即关闭。因此,OP 可能实际上认为根本不调用析构函数。考虑到这一点,我引用了我的答案。让我知道我是否错了。 @AI T - ideone.com/KEbu3

标签: c++


【解决方案1】:

您正在将 iostream 与非 ANSI conio.h 混合。

进行此更改:

// getch();
cin.get();

嘿,很快,C 出现了。至少在 OS X 上是这样。还有 Ubuntu。

【讨论】:

  • 是的。这似乎有道理。
  • 有一些方法可以让 C++ 和 C I/O 相互配合,但一般来说,不要费心,只使用其中一个即可。
  • @Mike DeSimone,喜欢 std::ios_base::sync_with_stdio 吗?这会涉及到最合理的 conio 实现吗?
  • 没试过,刚看到。它运作良好吗?我认为经常使用它会使 I/O 表现得更像是无缓冲的。
【解决方案2】:

在您使用 return 0 指令退出 main() 之前,您的程序一直处于运行状态。由于WriteLettersObj 是一个全局变量,它会在main() 开始之前被构造并在main() 完成之后被销毁,而不是在getch() 之后。

要查看打印输出,请将getch() 放在析构函数的末尾。

【讨论】:

  • 谢谢,我想我现在明白了。如果对象在 main 中实例化,您会看到它。由于是在main之前实例化的,所以在return 0之后就被销毁了。
  • 另一个你会听到人们说应该避免使用全局变量的原因。
  • iostream 对象 std::cout 也在 main 之前实例化。 C++ 运行时创建 std::cout 作为在 main 之前发生的初始化的一部分,并在 main 之后销毁它。如果你记得flush(),你应该会看到你的输出。问题是您正在写入 std::cout 对象,但随后使用 conio::getch() 激活竞争库到 STDOUT 的钩子,这会使事情变得混乱。 conio 可能不知道 iostream;我的猜测是 conio 正在关闭 STDOUT,因为它认为它拥有它,所以当 iostream 尝试进行最终写入和刷新时,STDOUT 消失了。
【解决方案3】:

我尝试在 Linux 和 Mac 上运行您的代码没有 getch,它运行得很好。 @iammilind 是正确的,您应该在析构函数中移动 getch。

【讨论】:

  • 我使用 getch() 作为暂停输出的一种方式,这样我就可以在窗口关闭之前看到那里的内容。有趣的是,如果我将 getch() 放入析构函数中,您会看到 C 正在输出。所以你是对的,它实际上是存在的,但是关闭窗口的时间不允许你看到它。
  • 保持窗口打开的更好方法是在“cmd”窗口中运行程序(假设您在 Windows 上)
猜你喜欢
  • 2014-07-06
  • 2017-08-16
  • 2012-04-11
  • 2022-01-16
  • 1970-01-01
  • 2015-08-26
  • 2013-11-07
相关资源
最近更新 更多