我的问题是大多数开发人员更喜欢错误处理,异常或错误返回代码.请具体说明语言(或语言家族)以及为什么您喜欢其中一种语言.
我出于好奇而问这个问题.我个人更喜欢错误返回代码,因为它们不那么具有爆炸性,并且如果不想要,也不会强制用户代码支付异常性能损失.
更新:感谢所有答案!我必须说,虽然我不喜欢代码流与异常的不可预测性.关于返回代码(以及他们的哥哥句柄)的答案会给代码添加大量的噪音.
注意:我不是在扮演魔鬼的拥护者或类似的东西 - 我只是真的好奇,因为我自己不在这个营地.
标准库中的大多数类型都具有可以抛出异常的变异函数(例如,如果内存分配失败)或者可以抛出异常的非变异函数(例如,超出边界的索引访问器).除此之外,许多自由函数可以抛出异常(例如operator new和dynamic_cast<T&>).
你如何在"我们不使用例外"的背景下实际处理这个问题?
你是否试图永远不会调用可以投掷的功能?(我无法看到它的规模如何,所以如果是这种情况,我很想知道你是如何实现这一目标的)
你没事吧和标准库中投掷,你把"我们不使用异常"为"我们从来不扔的异常我们的代码,我们从来没有赶上从异常等的代码"?
您是否通过编译器开关完全禁用异常处理?如果是这样,标准库的异常抛出部分如何工作?
编辑您的构造函数,它们是否会失败,或者按照惯例使用具有专用init函数的两步构造,该函数可以在失败时返回错误代码(构造函数不能),或者您是否执行其他操作?
编辑在问题开始后1周进行了一些小的澄清......下面的评论和问题中的大部分内容都集中在为什么方面的例外与"别的东西".我的兴趣是不是在这,但是当你选择做"别的东西",如何你处理标准库部件是不抛出异常?
今天我了解到swap不允许在C++中抛出异常.
我也知道以下内容也不能抛出异常:
还有其他人吗?
或许,是否有某种列表提到可能不会抛出的一切?
(显然,比标准本身更简洁.)
我刚刚玩了Java文件系统API,并提供了以下函数,用于复制二进制文件.最初的源代码来自Web,但我添加了try/catch/finally子句,以确保在出现错误之前,在退出函数之前缓冲流将被关闭(因此,我的操作系统资源被释放).
我减少了功能以显示模式:
public static void copyFile(FileOutputStream oDStream, FileInputStream oSStream) throw etc...
{
BufferedInputStream oSBuffer = new BufferedInputStream(oSStream, 4096);
BufferedOutputStream oDBuffer = new BufferedOutputStream(oDStream, 4096);
try
{
try
{
int c;
while((c = oSBuffer.read()) != -1) // could throw a IOException
{
oDBuffer.write(c); // could throw a IOException
}
}
finally
{
oDBuffer.close(); // could throw a IOException
}
}
finally
{
oSBuffer.close(); // could throw a IOException
}
}
Run Code Online (Sandbox Code Playgroud)
据我所知,我不能把这两个close()放在finally子句中,因为第一个close()可以抛出,然后,第二个不会被执行.
我知道C#有Dispose模式,可以使用using关键字来处理这个问题.
我甚至知道更好的C++代码(使用类似Java的API): …
假设你有一个类的std :: list.您可以通过两种方式制作此列表:1)
std::list<MyClass> myClassList;
MyClass myClass;
myClassList.push_front(myClass);
Run Code Online (Sandbox Code Playgroud)
使用此方法,将对象传递给列表时将调用复制构造函数.如果该类有许多成员变量,并且您多次进行此调用,则可能会变得昂贵.
2)
std::list<MyClass*> myClassList;
MyClass* myClass = new MyClass();
myClassList.push_front(myClass);
Run Code Online (Sandbox Code Playgroud)
此方法不会调用该类的复制构造函数.我不完全肯定在这种情况下会发生什么,但我认为该列表将创建一个新的MyClass*并分配参数的地址.事实上,如果你在堆栈而不是堆上创建myClass并让它超出范围,那么myClassList.front()是无效的,因此必须如此.
如果我错了,请反驳我,但我相信第二种方法对某些类来说效率更高.