如果某些条件未得到满足,从方法返回什么?

时间:2016-10-30 15:51:25

标签: c++ oop exception matrix

我正在写一个Matrice类(为了练习),当我编写方法来乘以两个Matrice对象时,我必须检查矩阵乘法是否满足某些条件:

Matrix Matrix::mul(const Matrix &mat)
{
    if(col != mat.row)
        //we cannot multiply in this case
    else
    {
        //create temp object result
        //perform multiplication
        return result;
    }   
}

现在我很好奇如果条件没有得到满足该怎么办,因为回到main.cpp我写了这样的话:

Matrix a = b.mul(c);

现在如果b和c不能相乘,我应该返回什么? 是抛出异常的最好方法,只是强迫使用该类发送兼容矩阵的人,还有另一种更好的方法吗?

4 个答案:

答案 0 :(得分:2)

不要退货,而是抛出exception

52.24.145.252.xip.io

您可以更多地抛出任何适合您情况的different exceptions

顺便说一句,您可以查看我的名为 Matrix on GitHub的项目,以获取如何创建此类以对矩阵进行操作的示例。

答案 1 :(得分:2)

要处理先决条件,你可以

  • 抛出异常。
  • 返回C ++ 17 std::optionalboost::optional
  • 致电std::terminate

破坏的前提条件通常意味着调用代码中的逻辑是错误的。因此,一种常见的方法是assert前提条件并进行广泛测试。理想情况下,这将确保前提条件永远不会被破坏。

为了帮助调用代码,最好为它提供至少一种方法来检查 调用是否会失败。

答案 2 :(得分:1)

有哪些可能的方法?

  1. 返回一些显示存在问题的中性值(例如空矩阵)
  2. 处理错误,但仅在调试时:例如使用assert()来验证和记录前后条件以及不变量。
  3. 抛出异常以通知存在问题:让调用者(或调用者的调用者)决定该怎么做。如果异常未捕获,则代码将中止。好消息是您可以提供其他错误信息。
  4. 您应该选择哪一个?

    如果错误情况频繁(几乎正常)并且经常调用该函数,则应使用解决方案(1)。我不建议你在这里使用它。

    如果预计不会发生错误情况,则可以使用解决方案(2),并且您确信防止了错误情况(例如,用户界面将阻止此类错误发生)。

    解决方案(3)适用于错误情况并非真正预期且无法真正预防的情况。据我所知,这应该是你的矩阵乘法的一个很好的候选解决方案。

    解决方案3的示例

    您可以使用exception(数学意义上的域,即参数是有效值,但函数未定义),而不是使用通用domain_error或创建您自己的特定目标对于该值)或invalid_argument

    // in your multiplication 
    ...
    if(col != mat.row)
        throw std::invalid_argument ("Matrix multiplication operand of incompatible size"); 
    ...
    
    // In the calling program: 
    ...
    try {
        a = b.mul(c);   
    } 
    catch (std::invalid_argument &e) {
        cout << "Invalid argument provided: " << e.what()<<endl;  
    }
    

答案 3 :(得分:0)

  

我该怎么回事?

这取决于您的要求。

  

是抛出异常的最佳方法

可能是。这取决于您的要求。

您有几个选择:

  1. 终止流程。开发人员可以分析核心转储以找出发生的情况。这样做的好处是很难错过一个错误。

  2. 甚至不测试函数中的前提条件。简单说明前提条件。如果调用者违反了前提条件,则行为未定义。这是最有效的解决方案,但依赖于函数的用户才能正确使用它。

  3. 使用assert测试条件。如果测试失败,则终止该过程。使用NDEBUG宏禁用断言,因此您可以禁用检查以获得最佳性能。这允许选择1.或2.取决于调试版本和发布版本,因此比任何一个都更灵活。

  4. 抛出异常。这允许调用者在无法处理时忽略失败的可能性,并让调用堆栈中的代码更高处理它......或者如果无法处理,则让进程终止。

  5. 返回std::optional。这允许调用者检查是否存在返回值并决定他们希望使用哪个1 ... 4选项来处理丢失的值。如果调用者忽略了不存在的返回值的可能性,则默认为2.(未定义的行为)。