我有一个可以正常工作的matrixType文件,但是现在我试图用类函数中的try,catch和throw语句替换if语句。我只是想了解一种功能,因此可以将其应用于其他功能。由于我确实尝试执行try和catch语句,但是它跳过了try语句,并导致了实际异常,该异常使程序完全停止。 我关注的一个功能是等号运算符 这是HeaderFile #pragma一次 #包括 #包括 #包括 #包括 #包括 #include
var isValid = function isValid(arr, arr2) {
var sum = function sum(array, n) {
return array.reduce(function (a, an) {
return a + (an === n);
}, 0);
};
return !arr2.some(function (n) {
return !arr.some(function (an) {
return an === n && sum(arr, an) === sum(arr2, n);
});
});
};
这是当前有效的class.cpp文件
using namespace std;
class matrixType
{
private:
int **matrix;
int row;
int col;
public:
const matrixType& operator=(const matrixType& mat);
}
然后这是源文件
#include "matrixType.h"
#include <iostream>
#include <iomanip>
#include <string>
#include <fstream>
#include <stdexcept>
#include <limits>
using namespace std;
const matrixType& matrixType::operator=(const matrixType& mat)
{
if (row != mat.row || col != mat.col)
{
cout << "The matrixes are not identical" << endl;
return *this;
}
for (int i = 0; i < row; i++)
{
for (int r = 0; r < col; r++)
{
matrix[i][r] = mat.matrix[i][r];
}
}
return *this;
}
所以最大的问题是如何抛出异常 我尝试过
#include <iostream>
#include <string>
#include <stdexcept>
#include <limits>
#include "matrixType.h"
using namespace std;
int main()
{
matrixType test1(3, 3);
matrixType test2(2, 2);
test1 = test2;
return 0;
}
这会导致实际异常弹出,但是当我离开if语句时,它将起作用,并且不会进入失败状态。如果我将if语句替换为上面的代码,是否有人看到我在做什么错了?
答案 0 :(得分:1)
首先,说明有关异常的含义。再进一步,我将解决您的代码出了什么问题。
在C ++中用英语抛出异常的含义大致是:“我已经不能处理这种情况,我现在正在放弃,我希望其他人可以处理这种情况。 ” catching 的含义大致是:“糟糕,有人搞砸了,但是我现在要对此做些事情。”考虑到这一点,让我们更具体地研究一下它的工作原理。
许多函数具有先决条件,这是函数在运行之前始终希望为真的条件。例如,squareRoot(double x)
函数可能有一个前提,即x
绝不能为负。当某个功能的先决条件被违反时,该功能自然会说“我现在要放弃,处理它!”因为调用该函数的人做错了事,squareRoot
不可能解决这个问题。看起来可能如下所示:
// precondition: x must not be negative
double squareRoot(double x){
if (x < 0.0){
// precondition is violated
throw std::runtime_error("input to squareRoot was negative");
// the function exits here!
// this point in code is not reachable
}
// otherwise, precondition is satisfied, it's safe to continue
...
return result;
}
在其他地方,在野外:
void myFunction(){
double x;
cout << "x = ";
cin >> x;
double y = squareRoot(x);
cout << ", y = " << y << '\n';
}
在这里,如果有人键入一个负数,则违反squareRoot
的前提,并引发异常。这意味着squareRoot
将不会正常返回,myFunction
也将不会返回。抛出异常后,所有事件都会被中断,直到您捕获到该异常为止,该异常可能发生在当前函数之外。
int main(){
try {
myFunction(); // this might throw
// if myFunction() throws, the following output will not happen!
cout << "Thanks! have a nice day.\n";
} catch (std::runtime_error e) {
// if myFunction() does throw, the error lands right here
cout << "Oops! an error occurred: " << e.what() << '\n';
}
return 0;
}
重要的是要注意,只有当某些东西是确实错误时,才应引发异常。异常不是不是替代普通程序逻辑,并且不是替代用于验证用户输入之类的东西。
关于自定义类:
在定义自定义类类型时,如果它具有复制构造函数,复制赋值运算符或析构函数,则可能意味着您的类具有敏感信息,需要特别注意清理和跟踪。如果您至少编写了这些功能之一,则应实现all three of them。否则,很容易在程序中引入内存泄漏,错误的数据共享以及各种有害的未定义行为。
关于您的副本分配运算符:
像a = b;
一样,副本分配运算符的目的是在运行后,左侧对象应该与右侧对象在逻辑上相同,右侧-手对象不应更改。此时,左侧对象的先前状态将丢失。逻辑上完全相同的意思是关于您的班级代表的问题。
在一个简单矩阵的情况下,当两个矩阵的所有元素的宽度,高度和值都相同时,我希望它们是相同的,并且我将相应地实现一个复制赋值运算符。例如:
Matrix& Matrix::operator=(const Matrix& other){
releaseMemory(); // clean up old data
resize(other.rows, other.cols); // allocate new data
for (int i = 0; i < rows; ++i){
for (int j = 0; j < cols; ++j){
this->data[i][j] = other.data[i][j]; // copy each value
}
}
return *this;
}
我将详细信息的实施留给您。通过阅读good C++ book,您应该能够找到有关如何重载运算符,编写自己的副本构造函数和析构函数以及良好实践的出色示例和详细说明。
答案 1 :(得分:-1)
实际上,当我在catch函数中包含return语句时,我发现必须使用return语句。