我有一个对象,它是 GNU 科学库中找到的矩阵结构的类接口(interface)
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;
}
我惊讶地发现矩阵对象 m 的行数被函数 test_function
修改为垃圾值,即使我将关键字 const 放在参数之前并且按值进行调用。
但最奇怪的是,如果我使用一个像这样通过引用调用的函数:
void test_function(const matrix &m){};
什么也没发生,一切似乎都很好。
据我所知,按值调用不应该能够修改函数的参数, 特别是如果函数像这种情况一样什么也不做,特别是如果我在函数原型(prototype)中的参数名称之前显式使用关键字 const...
任何帮助将不胜感激。
编辑:
我还将矩阵类的复制构造函数定义为
matrix& matrix::operator= (const matrix& src)
{
gsl_matrix_memcpy(m,src.m);
return *this;
}
它完成了 gsl_matrix 结构的完整拷贝(我猜)
编辑:
好吧,我想我终于明白了:按值调用函数创建一个浅复制对象,其中只包含指向真实对象的指针,当 test_function 终止时,所有局部变量都被销毁,因此矩阵类的析构函数(调用了它,但为了简洁起见,这里省略了它的定义),但通过这种方式,main 中的对象(本地 m 指向的)与本地变量一起被销毁。无论如何,我解决了定义正确的问题复制构造函数执行对象的完整(深层)复制,然后使用引用调用,这对于繁重的计算应该更好。非常感谢大家的帮助!
最佳答案
因为默认的复制构造函数只是进行浅复制,也就是说,它只是复制指针 m 的值,而不是分配新的值。
关于C++ 函数按值调用的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16209794/