2
class matrix
{
    int n;
    double **a;  //the "matrix"
public:
    matrix(int);
    ~matrix();
    int getN();
    matrix& operator=(matrix&);
    double& operator()(int,int);
    friend matrix& operator+(matrix,matrix);
    friend matrix& operator-(matrix,matrix);
    friend matrix& operator*(matrix,matrix);
    friend ostream& operator<<(ostream &,const matrix &);
};

matrix& operator+(matrix A,matrix B)
{
    int i,j,n=A.getN();
    assert(A.getN()==B.getN());
    matrix *C=new matrix(A.getN());
    for(i=0; i<n; i++)
    {
        for(j=0; j<n; j++)
        {
            (*C)(i,j)=A(i,j)+B(i,j);
        }
    }
    return *C;
}

これは算術演算子をオーバーロードする正しい方法ですか?

コードにメモリ リークはありますか?

コンストラクターは、最初にdoubleポインターの配列にメモリを割り当て、次に各ポインターにdoubleの配列を割り当てます。

4

2 に答える 2

6

新しい行列を値で返し、引数をconst参照で(少なくとも1つ)渡す必要があります。

matrix operator+(const matrix& A, const matrix& B);

これは、演算子の本体内で動的に割り当てるべきではないことを意味します。

パブリックメンバーメソッドまたはメンバー演算子のみを呼び出す場合は、非メンバー演算子をとして宣言する必要はありませんfriend

また、メンバー演算子などを実装し、それらの観点から非メンバー+=を実装するのが一般的な方法であることに注意してください。*=

matrix operator+(matrix A, const matrix& B)
{
  return A+=B;
}

余談ですが、行列の次元が正しいことを確認する必要があります。あなたのデザインでは、実行時にのみこれを行うことができます。別のアプローチは、行列クラステンプレートを作成することにより、コンパイル時に次元の正確さを強制することです。

template <typename T, size_t ROWS, size_t COLS> matrix;

トレードオフは、異なる次元の行列が異なるタイプであるということです。

于 2012-11-13T11:47:19.763 に答える
1

そのような設計はすぐに非効率になります。次のことを行うとどうなるかを考えてください。

matrix D = A + B + C ;

テンプレート メタ プログラミングを使用すると、役に立たない一時ファイルを作成しないようにするための非常に優れた可能性が得られます。Armadilloは、このアイデアの実に優れた実装です。

于 2012-11-13T11:55:56.547 に答える