相关疑难解决方法(0)

从析构函数中抛出异常

大多数人都说永远不会从析构函数中抛出异常 - 这样做会导致未定义的行为.Stroustrup指出"向量析构函数显式地为每个元素调用析构函数.这意味着如果元素析构函数抛出,向量破坏失败......实际上没有好的方法来防止从析构函数抛出的异常,所以库如果元素析构函数抛出",则不保证"(来自附录E3.2).

这篇文章似乎另有说法 - 抛出析构函数或多或少都没问题.

所以我的问题是 - 如果从析构函数抛出会导致未定义的行为,那么如何处理析构函数期间发生的错误?

如果在清理操作期间发生错误,您是否只是忽略它?如果它是一个可能在堆栈中处理但在析构函数中不正确的错误,那么从析构函数中抛出异常是否有意义?

显然,这类错误很少见,但可能.

c++ destructor exception raii

246
推荐指数
10
解决办法
11万
查看次数

构造函数作为函数try块 - 异常中止程序

我不确定这是编译器的问题还是我做错了.我正在使用Visual Studio 2013编译器.

我有一个类,我需要在构造函数初始化列表中获取大量资源,其中大部分都可以抛出异常.我在函数try块中包装了成员初始化列表,并在那里捕获了异常.但是我的程序仍然会中止,即使catch子句没有重新抛出异常.我不允许发布实际代码.所以我用这个等效的演示代码重现了这个问题.有人可以帮我解决这个问题吗?

#include <iostream>
using namespace std;
class A{
public:
    A() try : i{ 0 }{ throw 5; }
    catch (...){ cout << "Exception" << endl; }
private:
    int i;
};


int main(){
    A obj;
}
Run Code Online (Sandbox Code Playgroud)

在执行此代码时,我得到一个Windows警报"abort()已被调用".所以我猜系统将此视为未捕获的异常并调用terminate().

另一方面,如果我在try(catch)块中的main()中包装对象的构造,则正确捕获异常并且程序正常终止.

有人可以告诉我,如果我在这里做错了吗?

c++ c++11

48
推荐指数
3
解决办法
1994
查看次数

函数try块的目的是什么?

可能重复:
函数try块何时有用?
函数的try-catch语法之间的区别

此代码int在构造Dog类中的对象时抛出异常UseResources.该int异常由正常捕获try-catch块和代码输出:

Cat()  
Dog()  
~Cat()  
Inside handler
Run Code Online (Sandbox Code Playgroud)

#include <iostream>
using namespace std;

class Cat
{
    public:
    Cat() { cout << "Cat()" << endl; }
    ~Cat() { cout << "~Cat()" << endl; }
};

class Dog
{
    public:
    Dog() { cout << "Dog()" << endl; throw 1; }
    ~Dog() { cout << "~Dog()" << endl; }
};

class UseResources
{
    class Cat cat;
    class Dog dog;

    public:
    UseResources() : …
Run Code Online (Sandbox Code Playgroud)

c++ exception-handling exception function-try-block

9
推荐指数
1
解决办法
2187
查看次数

抛出数据成员的析构函数

我有一个类,它保存一个析构函数可以抛出的对象(它实际上是一个 tbb::task_group,但为了简单起见,我在这里将其命名为 MyObject)。

代码是这样的:

#include <stdexcept>

class MyObject {
public:
    MyObject() {}
    ~MyObject() noexcept(false) {}
};

class A {
public:
    A() {}
    virtual ~A() {}
};

class B : public A {
public:
    B() : A() {}
    ~B() {}

private:
    MyObject _object;
};
Run Code Online (Sandbox Code Playgroud)

并且编译器会引发以下错误:

重写函数的异常规范比基本版本更宽松

我不喜欢在整个代码中传播 noexcept(false) 的想法,因此我正在考虑使用指向 MyObject 的原始指针,并在析构函数之外删除它们(例如在 Close 函数中)。

处理这种情况的最佳方法是什么?

c++

9
推荐指数
2
解决办法
466
查看次数

函数try块,但不在构造函数中

只是一个简单的问题.两者之间有什么区别吗?

void f(Foo x) try
{
   ...
}
catch(exception& e)
{
   ...
}
Run Code Online (Sandbox Code Playgroud)

void f(Foo x)
{
    try { ... }
    catch (exception& e)
    {
        ...
    }
}
Run Code Online (Sandbox Code Playgroud)

如果不是,为什么函数尝试块(构造函数的初始化列表的情况被放在一边)?如果复制构造函数Foox传递给异常时抛出异常会发生什么f

c++ exception-handling

8
推荐指数
2
解决办法
2470
查看次数

Try/Catch块替换析构函数中的方法块

我最近的任务是在代码的一部分中查找内存泄漏.泄漏最终出现在特定对象的析构函数中......我发现了一些非常奇怪的东西.一位前同事写道:

File::~File()
try
{
    Clear();
}
catch (...)
{
    Log("caught exception");
}
Run Code Online (Sandbox Code Playgroud)

文件类继承自一些基类.我的第一个问题是:这是严格合法的C++吗?它在Visual Studio 2008中编译,但我向几个朋友/同事展示了它们,并且它们相当惊恐,它的工作原理.

但它实际上并没有按预期工作:这个对象继承的基类有一个现在永远不会被调用的析构函数(而不是如果你只是将析构函数包装在常规方法块中,将try/catch作为一部分)那个方法).

任何人都可以尝试解释为什么允许这样做,以及为什么没有调用基类析构函数?这里的析构函数并没有抛出.

c++ visual-studio-2008

6
推荐指数
1
解决办法
927
查看次数

为什么此C ++函数定义不需要大括号?

我在阅读Stroustrup的“编程-使用C ++的原理和实践”时发现,他包含了一个没有花括号的函数,却没有解释自己,网上的人说这是不可能的。

我已经编译了代码,并且可以正常工作。

void f()
    try {} 
    catch(...) {}
Run Code Online (Sandbox Code Playgroud)

我希望从中得到一个编译器错误,但是我没有,并且它工作正常。我正在使用C ++ 17。

c++ syntax function

6
推荐指数
1
解决办法
110
查看次数

主括号中的括号和返回值

我读了这段代码(由Bjarne Stroustrup撰写).我很困惑... main函数体不在{},函数不返回值(as int).它有效......为什么?

#include "std_lib_facilities.h" 

int main()
try
{
    cout<< "please enter two floating-point values separated by an operator\n The operator can be + - * or / : ";
    double val1 = 0;
    double val2 = 0;
    char op = 0;
    while (cin>>val1>>op>>val2) {   // read number operation number
        string oper;
        double result;
        switch (op) {
        case '+':
            oper = "sum of ";
            result = val1+val2; 
            break;
        case '-':
            oper = "difference …
Run Code Online (Sandbox Code Playgroud)

c++

4
推荐指数
1
解决办法
853
查看次数

ISO c ++ 15.3.10:为什么这种未定义的行为?

从相关的c ++标准部分:

引用构造函数的函数try-block的处理程序中的对象的任何非静态成员或基类,或该对象的析构函数导致未定义的行为.

例如.

T::~T() 
{
      try {
        this->nonstatic_member; // iff I read the quote correctly
      } catch( ... ) {
      }
}
Run Code Online (Sandbox Code Playgroud)

那为什么这个未定义的行为?

c++ language-lawyer c++11

4
推荐指数
2
解决办法
259
查看次数

从构造函数中捕获异常意味着我的实例后来超出了范围

我有一个类,其构造函数可能会抛出异常.这里有一些代码可以捕获异常:

try {
    MyClass instance(3, 4, 5);
}
catch (MyClassException& ex) {
    cerr << "There was an error creating the MyClass." << endl;
    return 1;
}
Run Code Online (Sandbox Code Playgroud)

但是当然,try/catch之后没有代码可以看到,instance因为它现在超出了范围.解决这个问题的一种方法是分别声明和定义instance:

MyClass instance;
try {
    MyClass instance(3, 4, 5);
}
...
Run Code Online (Sandbox Code Playgroud)

除了我的类没有适当的零参数构造函数.事实上,这里的这个案例是唯一一个这样的构造函数甚至有意义的案例:MyClass对象是不可变的,因为它的数据成员在构造之后都没有变化.如果我要添加一个零参数构造函数,我需要引入一些类似的实例变量is_initialized_,然后检查每个方法以确保该变量true在继续之前.对于这样一个简单的模式来说,这似乎太过冗长.

处理这种事情的惯用方法是什么?我是否需要将其填充并允许在初始化之前声明我的类的实例?

c++ constructor scope exception-handling try-catch

3
推荐指数
1
解决办法
169
查看次数

这个C++代码定义主要还是运行主?

我正在阅读Stroustrup的编程:原理和实践,并遇到了这段代码:

int main()
try {
    // our program
    return 0; //0 indicates success
}
catch (exception& e) {
    cerr << "error: " <<e.what() <<'\n';
    keep_window_open();
    return 1; // 1 indicates failure
}
catch (...) {
    cerr << "Oops: Unknown exception!\n";
    keep_window_open();
    return 2; //2 indicates failure
}
Run Code Online (Sandbox Code Playgroud)

起初我认为第一行称为主函数(其中包含代码的核心,并写在其他地方).然后我们只是尝试捕获main()内部可能发生的错误.但如果是这样的话,为什么在try块中说"我们的程序"呢?这让我觉得这段代码定义了main().但如果是这样,那么支架在哪里呢?也就是说,为什么不在int main() {第一线呢?

c++

2
推荐指数
1
解决办法
124
查看次数