0

C++ を使用して Matrix クラスを作成しようとしています。これまでのところ、次のことを達成しています。

  • マトリックスの作成
  • マトリックスの削除
  • マトリックス内の値の取得と設定

現在、すべての演算子 (つまり、+、-、*、/) をオーバーライドし、行列を返すことに取り組んでいます。私はこれについて多くの問題を抱えているので、誰かが助けてくれるかどうか疑問に思っていましたか?

また、マトリックスを新しいマトリックスにコピーする際にも問題が発生しているため、そのコードに関するヘルプをいただければ幸いです。

注: 私は Python のバックグラウンドを持っており、C++ を少し知っています。確かに、Python でたくさんの本当にクールなゲームや OOP を作成するのは素晴らしくクールですが、年をとったときに仕事を得るためには C++ を学ぶべきだと決めました。

これが私のコードです。プロトタイプとクラス定義、次にメインのヘッダーを含むヘッダーがあります。

matrix.h

#ifndef MATRIX_H
#define MATRIX_H

/*

// These are all of the error codes
// Upon changing errorcode, Matrix should reset to null/void

*/

#define ERROR_ROW_NP 1          // Row Number cannot be non-positive
#define ERROR_COLUMN_NP 2       // Column Number cannot be non-positive
#define ERROR_ROW_I 3           // Row Index Error
#define ERROR_COLUMN_I 4        // Column Index Error
#define ERROR_RC_MISMATCH 5     // # of Rows and Columns do not match

class Matrix {
    int row;
    int column;
    int elements;

    int *RC;

  public:
    int ERRORCODE;

    Matrix (void);                  // DONE
    Matrix (int, int);              // DONE
    ~Matrix (void);                 // DONE

    void Copy (Matrix);

    int get_value (int, int);       // DONE
    void set_value (int, int, int); // DONE

    int rc_match (Matrix);          // DONE

    Matrix operator+ (Matrix);
    Matrix operator- (Matrix);

    Matrix operator* (Matrix);

    Matrix operator* (int);
    Matrix operator/ (int);

};

#endif

matrix.cpp

#include "matrix.h"

Matrix::Matrix (void) {
    ERRORCODE = 0;

    row = 1;
    column = 1;
    elements = row * column;

    RC = new int[elements];

    for (int i=0; i< elements; i++) {
        RC[i] = 0;
    }
}

Matrix::Matrix (int r, int c) {
    ERRORCODE = 0;

    row = r;
    column = c;
    elements = row * column;

    RC = new int[elements];

    for (int i=0; i< elements; i++) {
        RC[i] = 0;
    }
}

Matrix::~Matrix (void) {
    delete[] RC;
}


// Copy will copy all of the contents of the toCopy
// matrix into itself; also resets it's own rows/columns
void Matrix::Copy (Matrix toCopy) {
    row = toCopy.row;
    column = toCopy.column;
    elements = toCopy.elements;

    RC = new int[elements];

    for (int i=0; i<elements; i++) {
        RC[i] = toCopy.RC[i];
    }
}

int Matrix::get_value (int r, int c) {
    return RC[(column*r)+c];
}

void Matrix::set_value (int r, int c, int value) {
    RC[(column*r)+c] = value;
}


int Matrix::rc_match (Matrix a) {
    if (
        (row == a.row)
        &&
        (column == a.column)
        ) {
            return (1);
    }
    else {
        return (0);
    }
}


Matrix Matrix::operator+ (Matrix a) {
    if (rc_match(a)) {
        Matrix OUT(row, column);
        int z;
        for (int i=0; i < row; i++) {
            for (int j=0; j < column; j++) {
                z = OUT.get_value(i, j) + a.get_value(i, j);
                OUT.set_value(i, j, z);
            }
        }
        return OUT;
    }
    else {
        Matrix OUT(1, 1);
        OUT.ERRORCODE = ERROR_RC_MISMATCH;
        return OUT;
    }
}

main.cpp

#include <iostream>
#include "matrix.h"

int main(void) {

    Matrix a(2, 2);
    a.set_value(0, 0, 3);
    a.set_value(0, 1, 2);

    Matrix b(2, 2);
    b.set_value(0, 0, 1);
    b.set_value(0, 1, 1);
    b.set_value(1, 0, 3);
    b.set_value(1, 1, 3);

    printf("%d %d\n", a.get_value(0, 0), a.get_value(0, 1));
    printf("%d %d\n", a.get_value(1, 0), a.get_value(1, 1));
    printf("\n");

    printf("%d %d\n", b.get_value(0, 0), b.get_value(0, 1));
    printf("%d %d\n", b.get_value(1, 0), b.get_value(1, 1));

    char t[1];
    printf("Press 'Enter' to continue...");
    std::cin.getline(t, 1);
    printf("\n");

    Matrix c;
    c.Copy(a+b);

    printf("%d %d\n", c.get_value(0, 0), c.get_value(0, 1));
    printf("%d %d\n", c.get_value(1, 0), c.get_value(1, 1));

    printf("Press 'Enter' to continue...");
    std::cin.getline(t, 1);
    printf("\n");

    return (0);
}

コンパイルおよび実行時に発生するエラーは次のとおりです。

Debug assertion failed! ...
Expression: _BLOCK_TYPE_IS_VALID(pHead ->nBlockUse)

「Enter」を押すとポップアップします

また、これは私の初めての投稿です。何か間違ったことをした場合は、お知らせください:]

EDIT2:私はそれを働かせました!@templatetypedef ありがとうございます。

私が使用した追加のコードは次のとおりです: (追加機能も間違っていることがわかりました) matrix.cpp

Matrix::Matrix(const Matrix& toCopy) {
    row = toCopy.row;
    column = toCopy.column;
    elements = toCopy.elements;

    RC = new int[elements];

    for (int i=0; i<elements; i++) {
        RC[i] = toCopy.RC[i];
    }
}

Matrix Matrix::operator+ (Matrix a) {
    if (rc_match(a)) {
        Matrix OUT(row, column);
        int z;
        for (int i=0; i < row; i++) {
            for (int j=0; j < column; j++) {
                z = get_value(i, j) + a.get_value(i, j);
                OUT.set_value(i, j, z);
            }
        }
        return OUT;
    }
    else {
        Matrix OUT(1, 1);
        OUT.ERRORCODE = ERROR_RC_MISMATCH;
        return OUT;
    }
}

だから今のところ私は代入演算子を調べます

4

2 に答える 2

0

@templatetypedef と @Kerrek が問題を特定しました。

std::vectorメモリを手動で管理する代わりに、マトリックス要素を保持するために使用することで簡単に解決できます。のコピー コンストラクターと代入演算子に関して、コピー コンストラクターと代入演算子はコンパイラによって自動的に実装され、std::vectorデストラクタ コードを取り除くことができます。Copyおまけとして、メモリリークとともに関数を削除できます。

于 2011-07-08T01:05:44.160 に答える
0

ここでの問題は、Matrixクラスにデストラクタがありますが、コピー コンストラクタまたはコピー代入演算子がないことだと思います。これは、 のコードでoperator +行列を返すときに、ディープ コピーではなく、行列の浅いコピーを取得することを意味します。これは、浅いコピーが でローカルに宣言された行列と同じ要素へのポインタを共有することを意味しますoperator +。このローカル変数がスコープ外になると、そのデストラクタが起動し、その行列のメモリが再利用されます。その結果、返された行列には割り当て解除されたメモリへのポインターが含まれ、未定義の動作が発生します。

Matrixこれを修正するには、クラスにコピー コンストラクターと代入演算子を実装してみてください。恥知らずな自己プラグとして、私はかつてこれを行う方法についてのガイドを書いたことがあり、ここで役立つかもしれません.

お役に立てれば!

于 2011-07-08T00:24:07.000 に答える