【发布时间】:2010-05-02 22:40:17
【问题描述】:
我正在尝试在实例化对象和处理对我的程序至关重要的对象的任何构造函数异常的两种方法之间做出决定,即如果构造失败,程序将无法继续。
我有一个 SimpleMIDIOut 类,它包含基本的 Win32 MIDI 函数。它将在构造函数中打开一个 MIDI 设备并在析构函数中关闭它。如果无法打开 MIDI 设备,它将在构造函数中抛出继承自 std::exception 的异常。
以下哪种方式捕获此对象的构造函数异常更符合 C++ 最佳实践
方法 1 - 堆栈分配的对象,仅在 try 块内的范围内
#include <iostream>
#include "simplemidiout.h"
int main()
{
try
{
SimpleMIDIOut myOut; //constructor will throw if MIDI device cannot be opened
myOut.PlayNote(60,100);
//.....
//myOut goes out of scope outside this block
//so basically the whole program has to be inside
//this block.
//On the plus side, it's on the stack so
//destructor that handles object cleanup
//is called automatically, more inline with RAII idiom?
}
catch(const std::exception& e)
{
std::cout << e.what() << std::endl;
std::cin.ignore();
return 1;
}
std::cin.ignore();
return 0;
}
方法 2 - 指向对象的指针、堆分配、更好的结构化代码?
#include <iostream>
#include "simplemidiout.h"
int main()
{
SimpleMIDIOut *myOut;
try
{
myOut = new SimpleMIDIOut();
}
catch(const std::exception& e)
{
std::cout << e.what() << std::endl;
delete myOut;
return 1;
}
myOut->PlayNote(60,100);
std::cin.ignore();
delete myOut;
return 0;
}
我更喜欢方法 2 中代码的外观,不必将我的整个程序塞进一个 try 块中,但是方法 1 在堆栈上创建对象,因此 C++ 管理对象的生命周期,这在与 RAII 理念相协调不是吗?
我仍然是这方面的新手,因此非常感谢您对上述内容的任何反馈。如果在这种情况下有更好的方法来检查/处理构造函数失败,请告诉我。
【问题讨论】:
-
+1 表示第一个问题问得好。
标签: c++ exception constructor