如何捕获构造函数异常? 我有一个C++类,它从构造函数上抛出一个异常。如何分配此类的本地实例(不使用new)并处理任何可能的异常,同时使try块范围尽可能小 本质上,我在寻找下面的java成语的C++等价: boolean foo() { Bar x; try { x = new Bar(); } catch (Exception e) { return false; } x.doSomething(); return true; }
我不想捕获如何捕获构造函数异常? 我有一个C++类,它从构造函数上抛出一个异常。如何分配此类的本地实例(不使用new)并处理任何可能的异常,同时使try块范围尽可能小 本质上,我在寻找下面的java成语的C++等价: boolean foo() { Bar x; try { x = new Bar(); } catch (Exception e) { return false; } x.doSomething(); return true; },c++,constructor,exception-handling,C++,Constructor,Exception Handling,我不想捕获x.doSomething(),中的异常,只捕获构造函数 我想我要寻找的是一种分离x的声明和初始化的方法 不使用堆分配和指针是否可以实现这一点?您必须在 bool foo() { std::unique_ptr<Bar> x; try { x = std::make_unique<Bar>(); } catch (const BarConstructorException& e) { return
x.doSomething()
,中的异常,只捕获构造函数
我想我要寻找的是一种分离x
的声明和初始化的方法
不使用堆分配和指针是否可以实现这一点?您必须在
bool foo() {
std::unique_ptr<Bar> x;
try {
x = std::make_unique<Bar>();
} catch (const BarConstructorException& e) {
return false;
}
x->doSomething();
return true;
}
通常,如果希望避免堆分配,则不能将局部变量的声明与其定义分开。因此,如果要将所有功能组合在一个函数中,则必须使用
try/catch
块围绕x
的整个范围:
boolean foo() {
try {
Bar x;
x.doSomething();
} catch (Exception e) {
return false;
}
return true;
}
是的,如果您将所有代码都放在
try
子句中,例如通过使用(以避免不必要的嵌套和作用域):
或者在try
子句中调用另一个执行实际工作的函数:
void real_foo()
{
Bar x;
x.doSomething();
}
bool foo() try
{
real_foo();
return true;
}
catch (std::exception const& e)
{
return false;
}
请注意,在构造函数中抛出异常通常不是一个好主意,因为这样会停止对象的构造,并且不会调用其析构函数
正如Holt所指出的,这还将捕获来自
doSomething
调用的异常。有两种解决方法:
如果您仍然想从构造函数中抛出异常,实际上还有第三种方法可以只捕获这些异常:使用上面的一个代码示例,只抛出那些
doSomething
永远无法抛出的特定异常,然后只捕获这些特定构造函数。否。从您的java示例中,您必须在以下两种可能性中进行选择:
没有指针:
bool foo() {
try {
Bar x;
x.doSomething();
} catch (Exception e) {
return false;
}
return true;
}
bool foo() {
Bar* x = nullptr;
try {
x = new Bar();
} catch (Exception e) {
return false;
}
x->doSomething();
delete x; // don't forget to free memory
return true;
}
#include <memory>
bool foo() {
std::unique_ptr<Bar> x;
try {
x = new Bar(); // until C++14
x = std::make_unique<Bar>(); // since C++14
} catch (Exception e) {
return false;
}
x->doSomething();
return true;
}
使用指针:
bool foo() {
try {
Bar x;
x.doSomething();
} catch (Exception e) {
return false;
}
return true;
}
bool foo() {
Bar* x = nullptr;
try {
x = new Bar();
} catch (Exception e) {
return false;
}
x->doSomething();
delete x; // don't forget to free memory
return true;
}
#include <memory>
bool foo() {
std::unique_ptr<Bar> x;
try {
x = new Bar(); // until C++14
x = std::make_unique<Bar>(); // since C++14
} catch (Exception e) {
return false;
}
x->doSomething();
return true;
}
或使用托管指针:
bool foo() {
try {
Bar x;
x.doSomething();
} catch (Exception e) {
return false;
}
return true;
}
bool foo() {
Bar* x = nullptr;
try {
x = new Bar();
} catch (Exception e) {
return false;
}
x->doSomething();
delete x; // don't forget to free memory
return true;
}
#include <memory>
bool foo() {
std::unique_ptr<Bar> x;
try {
x = new Bar(); // until C++14
x = std::make_unique<Bar>(); // since C++14
} catch (Exception e) {
return false;
}
x->doSomething();
return true;
}
#包括
布尔福(){
std::唯一的ptr x;
试一试{
x=新条();//直到C++14
x=std::make_unique();//自C++14
}捕获(例外e){
返回false;
}
x->doSomething();
返回true;
}
<代码> > P>此java习语自从C++ > bar x以来,不能很好地翻译成C++;代码>将需要默认构造函数,即使您的实际构造函数需要传递参数
我建议将这种语言打到这个程度-扩大try
块就足够了-但是如果你真的想缩小范围,那么你可以使用函数并依靠返回值优化来避免值拷贝:
Bar foobar()
{
try {
return Bar();
} catch (Exception& e){
/* Do something here like throwing a specific construction exception
which you intercept at the call site.*/
}
}
但实际上,您可以在构造时抛出一个特定的异常,因此完全避免使用此函数方法。您可以从C++17使用:
bool foo() {
std::optional<Bar> x; // x contains nothing; no Bar constructed
try {
x.emplace(); // construct Bar (via default constructor)
} catch (const Exception& e) {
return false;
}
x->doSomething(); // call Bar::doSomething() via x (also (*x).doSomething() )
return true;
}
bool-foo(){
std::可选x;//x不包含任何内容;未构造任何条
试一试{
x、 emplace();//构造栏(通过默认构造函数)
}捕获(常量异常和e){
返回false;
}
x->doSomething();//通过x调用Bar::doSomething()(也(*x).doSomething())
返回true;
}
在修订后的问题中,OP增加了以下要求:
“我不想捕获x.doSomething()
中的异常,只捕获[局部变量的]构造函数
翻译Java代码的简单方法
boolean foo() {
Bar x;
try {
x = new Bar();
} catch (Exception e) {
return false;
}
x.doSomething();
return true;
}
……到C++,则使用<代码> optalal><代码>类(如Barton Nackmann <代码> FalLabeB/EXCOR>,<代码> Boo::可选< <代码>或C++ 17代码>:STD::可选< <代码> < /P>
如果您不喜欢上述方法,则始终可以使用动态分配的Bar
实例,例如,使用std::unique_ptr
进行保证的清理,但这具有动态分配的一般开销。在Java中,大多数对象都是动态分配的,所以这似乎不是一个严重的缺点。但是在C++中,大多数对象都是超快堆栈,所以动态分配是一个非常慢的操作,与普通操作相比,因此动态分配的概念简单性必须与之相比。将所有内容放在try块内的成功路径上。StyyToLeLe:如果我不想从例如代码> x.DOMMETHONSE()/CUD>中捕获异常,只有构造函数中的例外情况“@安德烈孙”使用不同的异常,或者在内部异常块中放置<代码> x.DOMMETHOTHEN(/CUB>)> C++异常非常昂贵(对于C++速度瘾君子)。与Java不同,您不应该一开始就随意地抛出它们。如果您已经这样做了,那么就重新设计您的异常层次结构,并从x.doSomething()重新抛出内容代码>您知道要捕获什么异常吗?内存分配可能会失败,构造函数代码可能会失败…您可能需要添加一个