friend operator confusion - c++

I'm new to using .h/.cpp files and I'm trying to convert my .cpp to .h and .cpp and I'm running into this issue. It's erroring and I'm not sure how to resolve it. In Primitives.h I have:
friend Matrix operator+(const Matrix&, const Matrix&);
and in Primitives.cpp I had:
friend Matrix operator+ (const double b, const Matrix& a)
But thus far my attempts to change the format have not worked. Any tips?

You should do it like this:
// header
class Matrix
{
public:
friend Matrix operator+(const Matrix&, const Matrix&);
};
// source
Matrix operator+(const Matrix&, const Matrix&) { ... }
For short operators it may be more convenient to define the operator directly in the header file:
// header
class Matrix
{
public:
friend Matrix operator+(const Matrix&, const Matrix&) {
// code here
}
};

You should not use friend in implementation (.cpp file). You should use it at declaration (in .h file) only.

Try this
///your.h
class Matrix
{
//your class
friend Matrix operator+ (const double b, const Matrix& a);
};
////your.cpp
Matrix operator+ (const double b, const Matrix& a)
{
//your code
return yourobject;
}

Related

Get private element outside the class

First of all it's an exercise given to me so i can't change things and have to work with it.
I have a 2d vector aka a matrix. My header file looks like this
#include <vector>
#include <iostream>
using namespace std;
class Matrix{
private:
vector<vector<double>> 2d;
public:
explicit Matrix(unsigned int sizeY=0,unsigned int sizeX=0,double value= 0.0);
~Matrix() = default;
Matrix(const Matrix &other);
Matrix(Matrix &&other) = default;
Matrix& operator=(const Matrix &other);
Matrix& operator=(Matrix &&other) = default;
//other + - operators
//INDEX
vector<double>& at(unsigned int i);
const vector<double>& at(unsigned int i)const;
const vector<double>& operator[] (double m) const;
vector<double>& operator[] (double m);
};
Matrix operator+(const Matrix& d1, const Matrix& d2);
Matrix operator-(const Matrix& d1, const Matrix& d2);
ostream& operator<<(ostream &o, const Matrix& v);
istream& operator>>(istream &i, Matrix& v);
So now I implemented everything except the << and >> operator.
Now the question if i want to go through the 2d vec matrix is there another way to get the "depth"
outside the Matrix class except writing a getter ?
If the Matrix is N X M e.g. 4x4 i can get the 2nd 4 the "width" with something like 2d[0].size() but i cant figure out how I can get the "depth" otherwise then use a getter.
Also i cant change 2d to public or use templates.
I tried for around 2-3 hours myself and couldnt find any solution and maybe its not possible under the given conditions.
2d[0].size() is giving you the length of the first vector stored in 2d. To get the length of 2d you can just call the same directly on 2d.
2d.size() = length of 2d
2d[0].size() = length of first vector stored in 2d

Is it possible to implement move operator+/operator-/operator* for class of Matrix?

I am thinking on how can i define a class of real matrices NxN with the operations Add (Subtract) and Multiply. I am looking for Efficient Memory Usage.
class Matrix {
private:
std::size_t _size_n;
double **_pMatrix;
public:
Matrix(const size_t n);
~Matrix();
double &operator()(size_t, const size_t);
double operator()(size_t, const size_t) const;
size_t size_n() const { return _size_n; }
};
std::ostream &operator<<(std::ostream &, const Matrix &);
Matrix operator+(const Matrix&, const Matrix&);
Matrix operator-(const Matrix&, const Matrix&);
Matrix operator*(const Matrix&, const Matrix&);
Yes you can have additional overloads
Matrix/*&&*/ operator+(const Matrix&, Matrix&&);
Matrix/*&&*/ operator+(Matrix&&, const Matrix&);
Matrix/*&&*/ operator+(Matrix&&, Matrix&&);
To reuse memory of one of the temporary.
They can all be implemented with Matrix& operator += (Matrix&, const Matrix&)
by changing the order as + is symmetrical. operator - would require dedicated code.
Another way to optimize memory is to use expression templates instead of computing directly the result.
It has its drawback about lifetime issue (especially with auto) though.

Error happens when use friend function to manipulate private variables in template class in C++

I am writing a matrix operation library recently.And I want to overload operator s in my program, but Error happened when I use friend function to access private variables in the template class I was defined. (And it reports error only when I overload the operator '+', and the overload function of operation '-' doesn't report error.)
the template class I defined is below:
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
};
And the defination of this two overload functions are below:
// 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);
}
I've tested these two pieces of code seperately, the overload of operator '-' can be compiled correctly, but operator '+' can't.
The error imformations are below:
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'
And the IDE I use is VC++6.0.
friend Matrix operator+(const Matrix &a, const Matrix &b); is not a template. It is a non template friend function of a template class.
template<class T>Matrix<T> operator +(const Matrix<T> &m1, const Matrix<T> &m2) is a template. They are not the same function, as one is a template the other is not.
The easiest way to fix this is to put the body inline in the template class definition.
The second easiest way is to forward from operator+ to some static method, or some named function template. Forward declare it before the template class definition, friend it in the template class definition, implement it afterwarss.
(You actually want operator+ to be a non-template friend of a template class, as that makes it play much nicer with conversions.)
So do https://stackoverflow.com/a/13464246/1774667 but for a named function, not an operator. Call it add.
Then friend Matrix operator+(const Matrix &a, const Matrix &b){ return add(a,b); } which gives you the non-template friend operator of template class magic.

Implementing inner operator for derived class

Assume I have a general Matrix class, for which I have already implemented the operator * which performs the usual matrix multiplication.
Such an operator has the following signature :
Matrix operator*(const Matrix & ) const;
I now wish to implement another * operator for an inherited class Matrix3 that represents 3x3 matrices.
It would have the following signature :
Matrix3 operator*(const Matrix3 &) const;
I am looking for the proper way of implementing this operator in order to re-use the code already written for the base class, and to minimize cost (i.e. copying).
This should work just fine:
// Either return base class
Matrix operator*(const Matrix3& other) const
{
return Matrix::operator*(other);
}
// Or construct from a Matrix
Matrix3 operator*(const Matrix3& other) const
{
return Matrix3(Matrix::operator*(other));
}
// Either construct the Matrix data in the Matrix3
Matrix3(const Matrix& other)
{
// Initialize Matrix specifics
// Initialize Matrix3 specifics
}
// Or pass the Matrix to it's base class so it can take care of the copy
Matrix3(const Matrix& other) : Matrix(other)
{
// Initialize Matrix3 specifics
}

should friend functions be represented in UML diagrams?

Also, how exactly are overloaded operator member functions best formatted in a UML diagram?
Here is my class:
class matrix
{
friend ostream& operator << (ostream&, const matrix&);
friend bool operator == (const matrix &, const matrix &);
friend matrix operator - (const matrix &, const matrix &);
private:
int size;
int range;
int array[10][10];
public:
matrix(int);
matrix(int, int);
bool operator != (const matrix &) const;
matrix operator + (const matrix &) const;
const matrix & operator = (const matrix &);
};
and here is what I have of my UML diagram so far:
By placing the stereotype <<friend>> in front of the operation in the UML class diagram.
You will have to do it this way:
<<friend>> ostream& operator << (ostream&, const matrix&)
<<friend>> bool operator == (const matrix &, const matrix &)
<<friend>> matrix operator - (const matrix &, const matrix &)