C ++类构造函数引发异常

rul*_*lof 5 c++ constructor exception class

让我们考虑让一个带有构造函数抛出如下异常

class Class
{
    public:
        Class(type argument)
        {
            if (argument == NULL)
            {
                throw std::exception("Value cannot be null.\nParameter name: argument");
            }

            // Instructions
        }
    private:
        // Properties
}
Run Code Online (Sandbox Code Playgroud)

由于 构造函数可能会引发异常,因此我们无法直接声明对象

Class obj(argument); // Harmful
Run Code Online (Sandbox Code Playgroud)

这意味着必须使用try / catch来调用构造函数

try
{
    Class obj(argument);
}
catch (std::exception& ex)
{
    std::cout << ex.what() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

问题是我们只能在try块内使用对象。在try块之外使用它的唯一方法是声明一个Class * 指针,然后使用new关键字构造一个新对象,然后将其地址分配给前一个指针

Class* pObj;

try
{
    pObj = new Class(argument);
}
catch (std::exception& ex)
{
    std::cout << ex.what() << std::endl;
}
Run Code Online (Sandbox Code Playgroud)

那么,定义上一个以创建实例而不使用指针或动态内存分配的标准方法是什么?

先感谢您

Ben*_*ley 4

由于类构造函数可能会抛出异常,因此我们不能直接声明对象。

是的你可以。如果您确实有计划在函数中处理异常,则只需将其放入 try 块中。如果您没有这样的计划,那么就让异常传播(尽管您最终应该捕获它,只是为了提供报告(如果没有别的事情))。

但是,假设您确实有计划在函数中处理异常,那么解决方案很简单。

try {
    Class obj(argument);
    // use obj here, inside the try block
}
catch(...) { ... }

// not here, outside the try block
Run Code Online (Sandbox Code Playgroud)

编辑:根据您在下面的评论,要么您误解了我,要么我误解了您。也许需要一个具体的例子。假设这是使用您的类的函数:

void Foobar(type argument)
{
    Class obj(argument);
    obj.method1(1,2,3);
    obj.method2(3,4);
    int x = Wizbang(obj);
    gobble(x);    
}
Run Code Online (Sandbox Code Playgroud)

现在,您想要处理构造函数可能引发的异常Class。我的建议是将函数中的所有垃圾放入 try 块中,因此:

void Foobar(type argument)
{
    try
    {
        Class obj(argument);
        obj.method1(1,2,3);
        obj.method2(3,4);
        int x = Wizbang(obj);
        gobble(x);
    }
    catch(std::exception& e)
    {
        std::cout << e.what() << std::endl;
    }
}
Run Code Online (Sandbox Code Playgroud)

如果您无法做到这一点,请解释原因。您说过“我需要稍后才能使用该对象”,但您没有提供任何理由说明为什么“稍后”不能意味着“稍后在创建该对象的同一 try 块内”。因此,您的要求不完整。

  • @rullof:确切地说,您需要在哪里使用该对象?确切地说,为什么需要使用它的代码不能位于 try 块内? (5认同)