从C++函数声明可能的异常抛出有什么好处?换句话说,添加关键字throw()实际上做了什么?
我已经读过一个函数声明,例如void do_something() throw();应该保证没有异常来自do_something()函数; 然而,这似乎并不适用于内部调用的函数do_something(),从而使其成为弱保证.
请概述此语言功能的有用性(以及最佳用例).
我想知道为什么基类库中的.NET异常类默认有一些可变成员
Source,HelpLink和值Data,但不能改变其他任何像Message?StackTrace使它变得可变?将堆栈跟踪信息附加到现有跟踪是更好的设计(但仍然可变)?我只是在设计选择上很有意思......
我想在基类中抛出自己的异常Exception.有一个虚拟方法print将被子类覆盖.我只捕获类型Exception&并使用print来获取特定错误.问题是,一旦我抛出一个子类的引用,它就像它是基类一样被捕获.
这是一个例子:
#include <iostream>
using namespace std;
class Exception
{
public:
virtual void print()
{
cout << "Exception" << endl;
}
};
class IllegalArgumentException : public Exception
{
public:
virtual void print()
{
cout << "IllegalArgumentException" << endl;
}
};
int main(int argc, char **argv)
{
try
{
IllegalArgumentException i;
Exception& ref = i;
cout << "ref.print: ";
ref.print();
throw ref;
}
catch(Exception& e)
{
cout << "catched: ";
e.print();
}
} …Run Code Online (Sandbox Code Playgroud) 我知道我不应该从析构函数中抛出异常.
如果我的析构函数调用一个可以抛出异常的函数,那么如果我在析构函数中捕获它并且不进一步抛出它是否可以?或者它是否会导致中止,我不应该从析构函数中调用这些函数?
在异常return之后,它对任何值都有益throw吗?如果没有,可以return省略语句,是否有可能删除编译器错误C4715: not all control paths return a value?
提前致谢.
编辑:(示例代码)
for (ushort i = 0; i < itsNumUnits; ++i)
if (unitFormation[i] == unit)
{
return unitSetup[i];
}
else
throw unit;
return 0;
Run Code Online (Sandbox Code Playgroud) 在网上引用了很多文档,尤其是关于SO的文档,例如:在C#中重新抛出异常的正确方法是什么? "扔e"之间应该有区别 和"扔".
但是,来自:http://bartdesmet.net/blogs/bart/archive/2006/03/12/3815.aspx,
这段代码:
using System;
class Ex
{
public static void Main()
{
//
// First test rethrowing the caught exception variable.
//
Console.WriteLine("First test");
try
{
ThrowWithVariable();
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
//
// Second test performing a blind rethrow.
//
Console.WriteLine("Second test");
try
{
ThrowWithoutVariable();
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
}
private static void BadGuy()
{
//
// Some nasty behavior.
//
throw new Exception();
}
private …Run Code Online (Sandbox Code Playgroud) 我有以下C++代码,它给了我一个惊喜.问题是如果我抛出一些东西,除了在catch块内重新抛出,程序将通过调用abort终止并在GCC4中给出错误消息,"在抛出'int'实例后调用终止".如果我只是用"扔"; 重新扔进catch区,一切都会好的.
#include <iostream>
#include <exception>
#include <stdexcept>
using namespace std;
int main()
{
try{
throw std::string("first throw");
}
catch(std::string &x){
try{
std::cout << x << std::endl;
// throw; // if I use this line, all is fine.
throw int(2); // but if I use this line, it causes Abort() to be called
}
catch (int &k){
throw;
}
catch(...)
{
cout << "all handled here!"<< endl;
}
}
catch(...){
std::cout<< "never printed" << endl;
}
}
Run Code Online (Sandbox Code Playgroud) 如果line 8被注释,以下程序不能在g ++ 4.4中编译.为什么?似乎当我覆盖std::exception构造函数时,我也必须覆盖它的析构函数.这是什么原因?
#include<iostream>
#include<exception>
using namespace std;
class A : public exception {
public:
A(string msg) : _msg(msg) {}
//~A() throw(){}; // line 8
const char* what() const throw() { return _msg.c_str();}
private:
string _msg;
};
int main()
{
}
Run Code Online (Sandbox Code Playgroud)
编译错误是:
error: looser throw specifier for ‘virtual A::~A()’
Run Code Online (Sandbox Code Playgroud) 我有一个Exception类,我想在它抛出之前设置更多信息.我可以创建Exception对象,调用它的一些函数然后抛出它而不用它的任何副本吗?
我发现的唯一方法是抛出一个指向对象的指针:
class Exception : public std::runtime_error
{
public:
Exception(const std::string& msg) : std::runtime_error(msg) {}
void set_line(int line) {line_ = line;}
int get_line() const {return line_;}
private:
int line_ = 0;
};
std::unique_ptr<Exception> e(new Exception("message"));
e->set_line(__LINE__);
throw e;
...
catch (std::unique_ptr<Exception>& e) {...}
Run Code Online (Sandbox Code Playgroud)
但通常避免通过指针抛出异常,那么还有其他方法吗?
还可以选择通过构造函数设置所有选项,但如果将更多字段添加到类中并且您希望对要设置的字段进行细粒度控制,则可以快速变为不可扩展:
throw Exception("message"); // or:
throw Exception("message", __LINE__); // or:
throw Exception("message", __FILE__); // or:
throw Exception("message", __LINE__, __FILE__); // etc.
Run Code Online (Sandbox Code Playgroud) 我在某些视图中有一个按钮,它调用 ViewModel 中可能引发错误的函数。
Button(action: {
do {
try self.taskViewModel.createInstance(name: self.name)
} catch DatabaseError.CanNotBeScheduled {
Alert(title: Text("Can't be scheduled"), message: Text("Try changing the name"), dismissButton: .default(Text("OK")))
}
}) {
Text("Save")
}
Run Code Online (Sandbox Code Playgroud)
try-catch 块产生以下错误:
Invalid conversion from throwing function of type '() throws -> Void' to non-throwing function type '() -> Void'
Run Code Online (Sandbox Code Playgroud)
这是 viewModel 中的 createInstance 函数,taskModel 函数以同样的方式处理错误。
func createIntance(name: String) throws {
do {
try taskModel.createInstance(name: name)
} catch {
throw DatabaseError.CanNotBeScheduled
}
}
Run Code Online (Sandbox Code Playgroud)
如何正确捕获 SwiftUI 中的错误?