-1

我看到了很多例子,但我无法理解,如何通过简单的构造函数使用 try catch,我编写了一个示例程序:

class A
 {
   public:
    try {
       A()
        { cout << "in costr\n"; throw 10;}
    }//try closed
   catch (int a)
{ cout << "caught 1 \n"; }

 };

main()
 {
   A *ptr = new A;
   }
  1. 这个程序给出了编译错误
  2. 如果捕获到异常,对象会发生什么?
4

6 回答 6

8

try/catch代码应该是在一起的,你不能没有另一个。像这样的东西就是你所追求的:

A *ptr;
try {
    ptr = new A();
} catch (int a) {
    cout << "caught 1\n";
}

有关完整的工作示例,请参见以下程序:

#include <iostream>

class A {
    private:
        int a;
    public:
        A() { a = 7; throw 42; }
        int getA() { return a; }
};

int main (void) {
    A *ptr;
    try {
        ptr = new A();
    } catch (int b) {
        std::cout << "Exception: " << b << '\n';
        return -1;
    }
    std::cout << "Value: " << ptr->getA() << '\n';
    return 0;
}

有了throw 42里面,你会看到:

Exception: 42

这意味着main已经捕获了来自构造函数的异常。没有throw,你会看到:

Value: 7

因为一切都奏效了。


您的代码的主要问题似乎是:

  • 你有一个try不应该出现的声明。Try/catch块通常应该函数或方法中,紧跟在public关键字之后。

  • 如果您从构造函数中抛出异常,则不会在构造函数中捕获它。相反,您在调用构造函数的代码中捕获它(main在本例中)。

  • 如前所述trycatch它们不是独立的实体。


如果您尝试在构造函数中throwcatch则仍然需要将其放在构造函数本身中,例如:

#include <iostream>

class A {
    private:
        int a;
    public:
        A() {
            try {
                a = 7;
                throw 42;
            } catch (int b) {
                std::cout << "Exception A: " << b << '\n';
                throw;
            }
        }
        int getA() {return a;}
};

int main(void) {
    A *ptr;
    try {
        ptr = new A();
    } catch (int b) {
        std::cout << "Exception B: " << b << '\n';
        return -1;
    }
    std::cout << "Value: " << ptr->getA() << '\n';
    return 0;
}

这给了你:

Exception A: 42
Exception B: 42

特别注意该try/catch块是如何完成的并且构造函数中。

于 2012-08-10T05:20:24.567 回答
5

构造函数期间引发的异常问题由函数 try 块解决:

class A
 {
   public:
       A()
       try 
         { cout << "in costr\n"; throw 10;}
      catch(...)
        { cout << "exception caught"; throw;}
 };

但是他们正在解决的场景与您的示例不同。当类构造函数分配需要回收的资源时,需要函数 try 块。由于如果构造函数抛出类的析构函数不会运行(没有什么可以破坏,类没有从构造开始),解决问题的一种方法是在构造函数上使用函数 try 块。注意构造函数 try 块必须重新抛出异常或原来的异常,它们不能沉默捕获的异常。

有关您所问问题的更详细讨论(在构造函数期间存在异常的对象的范围/生命周期是多少),请参阅GOTW#66

于 2012-08-10T05:39:51.753 回答
5

如果您要做的是处理构造函数中抛出的异常而不重新抛出它,那么您必须将 try-catch 块放置在构造函数中,或围绕构造函数初始化列表:

class A
 {
  public:
   A() {
     try {
       // some code that could throw int
       cout << "in costr\n"; throw 10;}
     }//try closed
     catch (int a) {
       cout << "caught 1 \n";
     }
   }
   explicit A(int i) try : functionThatCanThow(i) catch (int)
   { }

 };

main()
{
   A *ptr = new A;
   A* ptr2 = new A(5);
}
于 2012-08-10T05:40:25.683 回答
2

你的意思是这样的:

#include <iostream>

class A
{
    public:
        A() 
        {   
            std::cout << "in costr\n";

            // An exception
            // of type `int`
            throw int(10); 
        }   
};

int main()
{
    // A try block were something may go wrong.
    try 
    {   
        A *ptr = new A;
    }   
    // A try is followed by one or more catch blocks
    // that can be activated if an exception is thrown
    catch (int a)
    {   
        std::cout << "caught 1 \n";
    }   
}
于 2012-08-10T05:22:52.933 回答
1

你必须把try和catch放在一起......

class A
{
  public:
    A() { cout << "in costr\n"; throw 10; }
};

int main()
{
    try
    {
        A* ptr = new A;
    }
    catch (int a)
    {
        cout << "caught " << a << '\n';
    }
}
于 2012-08-10T05:20:58.157 回答
0

为了增加答案,如果您想在对象构造过程中检查异常,您可以考虑这样的构造:

#include <iostream>

using std::cout;

struct Base {
    Base() { 
        cout << "Inside Base()\n";
        throw 1;
    }

private: 
    int i_;
};

struct Member {
    Member(int i) : i_(i) { 
        cout << "Inside Member()\n";
        throw 2;
    }

private: 
    int i_;
};

struct Derived : Base {
    Derived(int) try : member_(55) { cout << "Inside try{}\n"; } catch(int) { cout << "Inside catch()\n"; }

private: 
  Member member_;
};

int main() {
    Derived d(0);
    return 0;
}

在这里,看看在任何进一步的构造尝试之前如何捕获从基础抛出的,这会导致对象构造失败,同时提供足够的信息。在这种情况下,这是一个简单的例子。在实际场景中,您可能希望将异常传播到调用堆栈而不是吞下它。

于 2017-12-22T06:34:56.127 回答