【问题标题】:c++: Try catch on construction of a class with a const memberc ++:尝试使用 const 成员构造类
【发布时间】:2017-04-06 11:39:34
【问题描述】:

考虑以下类:

class MyClass
{
private:
    const unsigned int num;//num identifies the object. needs to be const
    unsigned int checkNum(unsigned int);// verifies that num has a valid value

public:
    MyClass(unsigned int n): num(checkNum(n)) {}
};

unsigned int MyClass:checkNum(unsigned int n)
{
    if (some_condition)
        throw std::invalid_argument("Invalid number");
    return n;
}

困难在于对象必须在try 块内构造,因为范围检查:

int main()
{
    try {
        MyClass mc(1000);
    }
    catch (std::invalid_argument &ia)
    {
        std::cout << ia.what();
    }
    return 0;
}

问题是mctry 块之外不可用。

可能的解决方案:

  1. try 块扩展到使用mc 的整个范围。在很多情况下不实用。

  2. 不要在构造函数中抛出异常,以后再抛出就来不及了。

我能想到的唯一可接受的解决方案是使用智能指针将声明带到 try 块之外:

int main()
{
    std::unique_ptr<MyClass> my_class_ptr;
    try {
        my_class_ptr = std::make_unique<MyClass>(1000);
    }
    catch (std::invalid_argument &ia)
    {
        std::cout << ia.what();
    }
    return 0;
}

还有其他/更好的解决方案吗?

【问题讨论】:

  • 我很确定你的意思是 checkNumcheckPin 是同一个名字。请在 SO 问题中发布真实代码。至少有一个答案似乎被此误导了。

标签: c++ exception constructor try-catch constants


【解决方案1】:

在您的第 1 点中,“在许多情况下不实用”完全是错误的。

try 块是您要处理故障的解决方案。

另一种方法是不处理它。


在其他新闻中,在您的第 2 点中,“不要让 MyClass::num const。不好,它应该在对象的持续时间内是不可变的。”是非常值得怀疑的。这在一定程度上取决于个人意见,但技术上没有问题。此外,const 和范围检查之间没有任何联系:假设的连接根本不存在。

【讨论】:

    【解决方案2】:

    mc 的构造被视为无效并通过异常“取消”时,您打算如何处理它?

    try 扩展到对象的整个范围非常有意义。

    mc 不应try 块之外访问。

    【讨论】:

      【解决方案3】:

      您应该在构造mc 对象之前验证 ID 号。不要在构造函数内部进行验证:

      class MyClass
      {
      private:
          const unsigned int num;
      
      public:
          MyClass(unsigned int n): num(n) {}
      };
      
      unsigned int checkNum(unsigned int n)
      {
          if (some_condition)
              throw std::invalid_argument("Invalid number");
          return n;
      }
      
      int main()
      {
          unsigned int num;
          try {
              num = checkNum(some_input);
          }
          catch (std::invalid_argument &ia)
          {
              std::cout << ia.what();
              return -1;
          }
          MyClass mc(num);
          return 0;
      }
      

      【讨论】:

        【解决方案4】:

        您可以使用函数try-block 来防止任何希望在try 块之外使用mc。 : >

        int main() try{
        
          return 0;
        } catch(...) {
        
        }
        

        【讨论】:

          猜你喜欢
          • 2017-02-10
          • 1970-01-01
          • 2013-04-11
          • 2021-09-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2012-01-06
          • 1970-01-01
          相关资源
          最近更新 更多