【问题标题】:Exception in constructor - C++ [duplicate]构造函数中的异常 - C++ [重复]
【发布时间】:2017-11-07 23:01:39
【问题描述】:

所以,我想限制在构造函数中使用 try-throw-catch 来创建没有参数的对象。这是我到目前为止所写的。但它不能正常工作,我该怎么办?没有错误,只返回 0。

#include <iostream>

using namespace std;

class Person
{
    public:
        Person(int _age)
        {
            age = _age;

            try
            {
                if (age == -1)
                {
                    throw 1;
                }
            }

            catch (int x)
            {
                cout << "You have to specify person's age" << endl;
            }
        }

    private:
        int age = -1;
};

int main(void)
{
    Person a();
    return 0;
}

【问题讨论】:

  • Person a(); 是一个不带参数并返回 Person 的函数的声明。它不是Person 类型变量的定义。你可以写 Person a;Person a{}; - 因为 Person 没有默认构造函数,所以它们不会编译。
  • 正确的做法是在 main 函数中使用 try-catch 来创建 Person 实例。这样,即使年龄无效,也会创建 Person 实例,问题是,是否应该允许 Person 对象的年龄无效?
  • 另外,即使你说Person a;,也不会编译,因为默认构造函数不会被合成,因为你提供了一个非默认构造函数。
  • 如果您不想在没有参数的情况下调用该函数,请不要创建默认构造函数。
  • 您的代码允许创建一个年龄为 -5 的人。您可能需要将 age 视为 无符号 整数,因为负年龄没有意义。

标签: c++ exception


【解决方案1】:

问题一:

Person a();

令人烦恼的解析。这没有声明变量并调用构造函数,它声明了函数a,它返回一个Person

解决方案:

Person a;

但这会引发问题 2:

没有默认构造函数。指定 Person(int _age) 定义了一个非默认构造函数,这会阻止编译器生成默认(无参数)构造函数。这实际上是您的胜利,因为您的既定目标是无法在没有参数的情况下构造 Person

你不能

Person a;

你必须

Person a(<an int>);

这不会阻止用户

Person a(-1);

这对anyone not from Ork. 来说意义不大,这为在构造函数中使用异常提供了一个很好的示例,并暴露了问题 3:

构造函数有两种方法不结束程序:使用构造对象和抛出异常。在构造函数中抛出和捕获表示构造失败的异常都是不寻常的,因为它允许返回构造不正确的对象。

所以

Person(int _age)
{
    age = _age;

    try
    {
        if (age == -1) // probably should reject age < 0
        {
            throw 1;
        }
    }

    catch (int x)
    {
        cout << "You have to specify person's age" << endl;
    }
}

实际上会导致您试图避免的问题。

解决方案:

Person(int _age)
{
    age = _age;
    if (age == -1)
    {
        throw 1;
    }
}

main

int main(void)
{
    try
    { 
        Person a();
        // use a
        return 0;
    }
    catch (int x)
    {
        cout << "You have to specify person's age" << endl;
        return -1;
    }
}

可以进行一项重大改进:使异常有意义

抛出 1 包含的上下文太少,没有意义。您可以抛出并捕获自定义异常,但对于像 std::runtime_error 这样简单的事情,来自 `

Person(int _age)
{
    if (_age == -1)
    {
        throw std::runtime_error("You have to specify person's age");
        // do not new an exception. It's hard to clean up and free the memory
    }
    age = _age; // why assign then test? Save a clock cycle.
}

main

int main(void)
{
    try
    { 
        Person a();
        // use a
        return 0;
    }
    catch (const std::exception & e) // where possible catch by constant reference
    {
        cout << e.what() << endl;
        return -1;
    }
}

【讨论】:

    猜你喜欢
    • 2013-05-02
    • 2023-04-07
    • 1970-01-01
    • 2019-07-11
    • 1970-01-01
    • 2019-03-11
    • 2013-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多