首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >OOP C++操作符中的问题

OOP C++操作符中的问题
EN

Stack Overflow用户
提问于 2015-01-05 03:44:25
回答 3查看 140关注 0票数 1

我对C++还是个新手。我的问题是编写一个关于矩阵的OOP C++程序(创建一个矩阵类并向这个类添加一些方法)以下是我的代码:

代码语言:javascript
复制
#include <iostream>
#include <iomanip>

using namespace std;

class Matrix 
{
    private:
        int col, row;
        double *a;
    public:
        Matrix(int col = 1, int row = 1) {
            this->col = col; this->row = row;
        }
        ~Matrix() {
            delete a;
            col = row = 0;
        }
        void insertMatrix() {
            a = new double[this->col * this->row];
            for (int i = 0; i < this->row; i++)
                for (int j = 0; j < this->col; j++) {
                    cout << endl << "a[" << i + 1 << "][" << j + 1 << "] = ";
                    cin >> this->a[i * this->col + j];
                }
        }
        void printMatrix() {
            for (int i = 0; i < this->row; i++) {
                for (int j = 0; j < this->col; j++)
                    cout << setw(9) << this->a[i * this->col + j];
                cout << endl;
            }
            cout << endl;
        }
        int getCol() {
            return col;
        }
        int getRow() {
            return row;
        }
        Matrix operator+(Matrix);
        Matrix operator-(Matrix);
};

Matrix Matrix::operator+(Matrix x) {
    if (x.col != col || x.row != row) {
        cout << endl << "Can't add these two matrices";
        exit(0);
    }
    Matrix sum(x.col, x.row);
    sum.a = new double(sum.col * sum.row);
    for (int i = 0; i < this->col * this->row; i++)
        sum.a[i] = a[i] + x.a[i];
    return sum;
}

Matrix Matrix::operator-(Matrix x) {
    if (x.col != this->col || x.row != this->row) {
        cout << endl << "Can't subtract these two matrices";
        exit(0);
    }
    Matrix dif(this->col, this->row);
    dif.a = new double(dif.col * dif.row);
    for (int i = 0; i < this->col * this->row; i++)
        dif.a[i] = this->a[i] - x.a[i];
    return dif;
}

int main()
{
    int row, col;
    cout << endl << "Column = "; cin >> col; cout << endl << "Row = "; cin >> row;
    Matrix A(col, row), B(col, row);
    A.insertMatrix(); B.insertMatrix();
    cout << "Matrix A: " << endl; A.printMatrix(); 
    cout << "Matrix B: " << endl; B.printMatrix();
    cout << "Matrix (A + B)" << endl; (A + B).printMatrix();
    cout << "Matrix (A - B)" << endl; (A - B).printMatrix();
}

我看不出有任何错误。我可以编译这个程序。但每次我尝试输入一些数字时,程序总是冻结,并显示“停止工作”的消息,并得到错误的答案。我在Windows8中使用的是Orwell Dev C++,有人能解释一下原因吗?

EN

回答 3

Stack Overflow用户

发布于 2015-01-05 03:55:19

一个错误是您错误地使用了new

代码语言:javascript
复制
 sum.a = new double(sum.col * sum.row);

上面的代码动态创建了一个单精度的双精度值,并将该值初始化为sum.col * sum.row

您应该使用new[]

代码语言:javascript
复制
 sum.a = new double[sum.col * sum.row];

那么在使用new[]时,您必须使用delete[],而不是delete

另一个错误是您没有在构造函数中初始化a指针。当矩阵被销毁时,析构函数将在指向谁知道在哪里的指针上发出一个delete

因此,这个简单的一行程序有问题:

代码语言:javascript
复制
int main() {
   Matrix m;
}  // < -- problems here 

修复方法是确保您的指针已初始化:

代码语言:javascript
复制
Matrix(int mcol = 1, int mrow = 1) : a(0), col(mcol), row(mrow) {}

请注意,a现在已初始化为0。还要注意成员初始化列表的用法。

然而,另一个错误是您的Matrix类缺少用户定义的复制构造函数和赋值操作符。当您通过值返回或传递Matrix时,就像这里所做的那样:

代码语言:javascript
复制
Matrix Matrix::operator+(Matrix x)

拷贝只会在指针上做一次浅拷贝,因此你的程序会有内存泄漏,双重释放错误等。请阅读“规则3":

What is The Rule of Three?

其他问题:

不要在类代码中调用 exit(0) 。如果我想使用你的Matrix类,并且我给operator +一个不正确大小的Matrix,请不要关闭我的应用程序!相反,抛出一个异常,或者发出一个assert()

查看此处:exit() call inside a function which should return a reference

票数 5
EN

Stack Overflow用户

发布于 2015-01-05 03:59:22

程序中的主要问题是,在重载的运算符中,返回一个堆栈分配的Matrix对象,该对象将调用复制构造函数。

但是由于您没有定义,编译器将为您生成它,执行逐位复制,这意味着复制的对象中的d指针将指向与堆栈中的对象相同的位置。

因此,析构函数被调用两次。

当离开函数overloads;

  • when销毁复制的对象时销毁,这紧跟在这一行之后:

(A + B).printMatrix();

这就是为什么你的程序会异常终止,出现类似下面这样的错误:

错误在`./rez':():无效的下一个大小(快速):0x00000000020390c0

正如其他人所建议的那样,如果您遵循3 (或C++11/14中的5)的规则,您就不会遇到这个问题。

票数 4
EN

Stack Overflow用户

发布于 2015-01-05 03:57:00

另一个错误是对规则3的公然违反;复制您的Matrix会破坏它的所有权语义。

为什么不使用std::vector<double>来代替呢?

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/27769607

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档