2

GNU Scientific Library にある行列構造体へのクラス インターフェイスであるオブジェクトがあります。

typedef double real_t;
typedef unsigned short index_t;
class matrix
{
        gsl_matrix* m;
    public:
        matrix(index_t rows, index_t columns, real_t val);
}

matrix::matrix(index_t rows, index_t columns, real_t val)
{
    m=gsl_matrix_alloc(rows,columns);
    gsl_matrix_set_all(m, val);
    return;
}

index_t matrix::rows(void)
{
    return m->size1;
}

index_t matrix::columns(void)
{
    return m->size2;
}

問題は、次のような値で行列オブジェクトを取得する関数を使用する場合です。

void test_function(const matrix m){};

このようなプログラムで使用します

int main()
{
    matrix m(4,4,1);
    cout << m.rows() << '\t' << m.columns() << endl;
    test_function(m);
    cout << m.rows() << '\t' << m.columns() << endl;
}

驚くべきことに、引数の前にキーワード const を置き、呼び出しが値によって行われたとしても、行列オブジェクト m の行数が関数によってtest_functionガベージ値に変更されることがわかりました。しかし、最も奇妙なことは、次のような参照による呼び出しを利用する関数を使用する場合です。

void test_function(const matrix &m){};

何も起こらず、すべてが順調に見えます。

私の知る限り、特に関数がこの場合のように何もしない場合、特に関数プロトタイプの引数名の前にキーワード const を明示的に使用する場合、値による呼び出しは関数の引数を変更できないはずです。 ..

どんな助けでも大歓迎です。

編集:

また、マトリックス クラスのコピー コンストラクターを次のように定義しました。

matrix& matrix::operator= (const matrix& src)
{
    gsl_matrix_memcpy(m,src.m);
    return *this;
}

これは、gsl_matrix 構造体の完全なコピー (推測) を行います

編集:

わかりました、ようやく理解できたと思います: 値による呼び出し関数は、実際のオブジェクトへのポインターを含む浅いコピー オブジェクトを作成します。test_function が終了すると、すべてのローカル変数が破棄されるため、マトリックス クラスのデストラクタ (簡潔にするためにここでは省略されています) が呼び出されますが、この方法では、メインのオブジェクト (ローカル m が指す) がローカル変数と共に破棄されます. とにかく、適切なコピーコンストラクターを定義する問題を解決しましたオブジェクトの完全な (深い) コピーを実行してから、重い計算に適した参照渡しを使用します。助けてくれて本当にありがとう!

4

2 に答える 2