C++中使用友元函数操作模板class中的私有变量时出错
Error happens when use friend function to manipulate private variables in template class in C++
我正在写一个矩阵运算库recently.And我想在我的程序中重载operators,但是当我使用友元函数访问模板中的私有变量时发生错误class我被定义了. (而且只在我重载运算符'+'时才报错,'-'运算符的重载函数不报错。)
我定义的模板 class 如下:
template<class T>
class Matrix
{
int col;
int row;
T *matrix;
public:
Matrix(T *m, int row1, int col1):matrix(m), row(row1), col(col1){}
Matrix(int row1, int col1):row(row1), col(col1)
{
matrix = new T[row*col];
cout<<"Have set the shape of the matrix, but should use create() to initialize the matrix!"<<endl;
}
Matrix(){}
~Matrix(){}
void show();
UINT create(T *m);
UINT zeros(int size);
UINT eye(int size);
// the overload function statement
friend Matrix operator+(const Matrix &a, const Matrix &b);
friend Matrix operator-(const Matrix &a, const Matrix &b);
Matrix matrix_T(); // transpose the matrix
Matrix matrix_Inv(); // calculate matrix's inverse
Matrix matrix_Adjoint(); // calculate the adjoint matrix
};
这两个重载函数的定义如下:
// report error: can't access private member declared in class
template<class T>
Matrix<T> operator +(const Matrix<T> &m1, const Matrix<T> &m2)
{
if (m1.col!=m2.col || m1.row!=m2.row)
{
cout<<"These two matrices can't be plused!"<<endl;
exit(0);
}
T *tmp = new T[m1.col*m1.row];
for (int i=0; i<m1.row; i++)
{
for (int j=0; j<m1.col; j++)
{
tmp[i*m1.col+j] = m1.matrix[i*m1.col+j] + m2.matrix[i*m1.col+j];
}
}
return Matrix<T>(tmp, m1.row, m1.col);
}
// this defination didn't report error
// and if I only run this code, there is nothing wrong
template<class T>
Matrix<T> operator -(const Matrix<T> &m1, const Matrix<T> &m2)
{
if (m1.col!=m2.col || m1.row!=m2.row)
{
cout<<"These two matrices can't be plused!"<<endl;
exit(0);
}
T *tmp = new T[m1.col*m1.row];
for (int i=0; i<m1.row; i++)
{
for (int j=0; j<m1.col; j++)
{
tmp[i*m1.col+j] = m1.matrix[i*m1.col+j] - m2.matrix[i*m1.col+j];
}
}
return Matrix<T>(tmp, m1.row, m1.col);
}
我分别测试了这两段代码,运算符'-'的重载可以正确编译,但是运算符'+'不能。
错误信息如下:
f:\program\c++\matrixoperate\matrixdefine.h(134) : error C2248: 'col' : cannot access private member declared in class 'Matrix<int>'
f:\program\c++\matrixoperate\matrixdefine.h(6) : see declaration of 'col'
f:\program\c++\matrixoperate\demo.cpp(14) : see reference to function template instantiation 'class Matrix<int> __cdecl operator +(const class Matrix<int> &,const class Matrix<int> &)' being compiled
f:\program\c++\matrixoperate\matrixdefine.h(134) : error C2248: 'col' : cannot access private member declared in class 'Matrix<int>'
f:\program\c++\matrixoperate\matrixdefine.h(6) : see declaration of 'col'
我用的IDE是VC++6.0.
friend Matrix operator+(const Matrix &a, const Matrix &b);
不是模板。它是模板的非模板友元函数 class.
template<class T>Matrix<T> operator +(const Matrix<T> &m1, const Matrix<T> &m2)
是模板。它们不是同一个函数,一个是模板,另一个不是。
解决此问题的最简单方法是将正文内联到模板 class 定义中。
第二个最简单的方法是从 operator+
转发到某个静态方法或某个命名函数模板。在模板 class 定义之前转发它,在模板 class 定义中将其友化,之后实现它。
(您实际上希望 operator+
成为模板 class 的非模板好友,因为这样可以更好地处理转换。)
也是如此,但对于命名函数,而不是运算符。称之为 add
.
然后 friend Matrix operator+(const Matrix &a, const Matrix &b){ return add(a,b); }
给你模板的非模板友元操作符 class magic.
我正在写一个矩阵运算库recently.And我想在我的程序中重载operators,但是当我使用友元函数访问模板中的私有变量时发生错误class我被定义了. (而且只在我重载运算符'+'时才报错,'-'运算符的重载函数不报错。) 我定义的模板 class 如下:
template<class T>
class Matrix
{
int col;
int row;
T *matrix;
public:
Matrix(T *m, int row1, int col1):matrix(m), row(row1), col(col1){}
Matrix(int row1, int col1):row(row1), col(col1)
{
matrix = new T[row*col];
cout<<"Have set the shape of the matrix, but should use create() to initialize the matrix!"<<endl;
}
Matrix(){}
~Matrix(){}
void show();
UINT create(T *m);
UINT zeros(int size);
UINT eye(int size);
// the overload function statement
friend Matrix operator+(const Matrix &a, const Matrix &b);
friend Matrix operator-(const Matrix &a, const Matrix &b);
Matrix matrix_T(); // transpose the matrix
Matrix matrix_Inv(); // calculate matrix's inverse
Matrix matrix_Adjoint(); // calculate the adjoint matrix
};
这两个重载函数的定义如下:
// report error: can't access private member declared in class
template<class T>
Matrix<T> operator +(const Matrix<T> &m1, const Matrix<T> &m2)
{
if (m1.col!=m2.col || m1.row!=m2.row)
{
cout<<"These two matrices can't be plused!"<<endl;
exit(0);
}
T *tmp = new T[m1.col*m1.row];
for (int i=0; i<m1.row; i++)
{
for (int j=0; j<m1.col; j++)
{
tmp[i*m1.col+j] = m1.matrix[i*m1.col+j] + m2.matrix[i*m1.col+j];
}
}
return Matrix<T>(tmp, m1.row, m1.col);
}
// this defination didn't report error
// and if I only run this code, there is nothing wrong
template<class T>
Matrix<T> operator -(const Matrix<T> &m1, const Matrix<T> &m2)
{
if (m1.col!=m2.col || m1.row!=m2.row)
{
cout<<"These two matrices can't be plused!"<<endl;
exit(0);
}
T *tmp = new T[m1.col*m1.row];
for (int i=0; i<m1.row; i++)
{
for (int j=0; j<m1.col; j++)
{
tmp[i*m1.col+j] = m1.matrix[i*m1.col+j] - m2.matrix[i*m1.col+j];
}
}
return Matrix<T>(tmp, m1.row, m1.col);
}
我分别测试了这两段代码,运算符'-'的重载可以正确编译,但是运算符'+'不能。 错误信息如下:
f:\program\c++\matrixoperate\matrixdefine.h(134) : error C2248: 'col' : cannot access private member declared in class 'Matrix<int>'
f:\program\c++\matrixoperate\matrixdefine.h(6) : see declaration of 'col'
f:\program\c++\matrixoperate\demo.cpp(14) : see reference to function template instantiation 'class Matrix<int> __cdecl operator +(const class Matrix<int> &,const class Matrix<int> &)' being compiled
f:\program\c++\matrixoperate\matrixdefine.h(134) : error C2248: 'col' : cannot access private member declared in class 'Matrix<int>'
f:\program\c++\matrixoperate\matrixdefine.h(6) : see declaration of 'col'
我用的IDE是VC++6.0.
friend Matrix operator+(const Matrix &a, const Matrix &b);
不是模板。它是模板的非模板友元函数 class.
template<class T>Matrix<T> operator +(const Matrix<T> &m1, const Matrix<T> &m2)
是模板。它们不是同一个函数,一个是模板,另一个不是。
解决此问题的最简单方法是将正文内联到模板 class 定义中。
第二个最简单的方法是从 operator+
转发到某个静态方法或某个命名函数模板。在模板 class 定义之前转发它,在模板 class 定义中将其友化,之后实现它。
(您实际上希望 operator+
成为模板 class 的非模板好友,因为这样可以更好地处理转换。)
也是如此,但对于命名函数,而不是运算符。称之为 add
.
然后 friend Matrix operator+(const Matrix &a, const Matrix &b){ return add(a,b); }
给你模板的非模板友元操作符 class magic.