Declaration inside class or outside? - c++

Given the following functions:
1)
IntMatrix operator+(const IntMatrix &matrix, int scalar);
2)
IntMatrix operator+(int scalar, const IntMatrix &matrix);
Which take a scalar and adds it to every member in the Matrix, Should I declare them outside the class (like what is shown above) or inside my class?
In collage they thought as that if we need it to work in both directions (symmetrical behaviour) we declare it out but here it's a little bit complicated...

Function 1 can be written inside the class, as a member function, but function 2 must be written as a non-member function, since the left hand side is not a IntMatrix.
I would suggest writing a operator+= that takes an int as a member function. Then you can easily call that from both operator+, which you can write as non-members.
So your operator+ (as non-members) would look like this:
IntMatrix operator+(IntMatrix matrix, int scalar) {
return matrix += scalar;
}
IntMatrix operator+(int scalar, IntMatrix matrix) {
return matrix += scalar;
}

Related

performing function with classes of similar type C++

I want to implement a representation of matrices.
for that I have two types of matrices - regular and sparse, which differ in their
implementation - one holds a vector, and the second a map of indices and value,
both inherit from Matrix class.
I want to implement the + operator, which operates on Matrix and receives another Matrix.
but when I implement the + operator, I might receive as parameter sparse/regular matrix.
is there any way to receive a matrix, which I don't know what type of the 2 it is,
and perform the + operator?
meaning, if in class SparseMatrix I receive sparse/regular matrix, how can I implement the operator such that no matter which of the two types I get, it will work?
Matrix & operator+ (Matrix other)
{
...
}
I would probably implement two versions of operator+, and let them call a helper template method:
template <typename ITER>
Matrix add (ITER other_it) {
//...
}
Matrix operator+ (RegularMatrix other)
{
return add(other.begin());
}
Matrix operator+ (SparseMatrix other)
{
return add(other.begin());
}
You could make operator+ a template, but this way makes sure you only allow those Matrix types.
As was pointed out to me, you should not return a reference from +, as the result needs to be point to an instance that exists after the operation returns.
We can use polymorphism to create different implementations of a Matrix. Through the common interface of Matrix, each implementation can interact.
class Matrix
{
class iterator { ... }
friend Matrix operator+(const Matrix &lhs, const Matrix &rhs)
{
// iterate, add, and return new matrix
}
};
class SpareMatrix : public Matrix
{
iterator begin() { ... }
};
class Matrix
{
public:
virtual ~Matrix() {}
virtual Matrix& operator+(Matrix& other) = 0;
};
class MatrixSparse : public Matrix
{
public:
virtual ~MatrixSparse() {}
virtual Matrix& operator+(Matrix& other)
{
MatrixSparse* sparse = dynamic_cast<MatrixSparse*>(&other);
// TODO
}
};
class MatrixRegular : public Matrix
{
public:
virtual ~MatrixRegular() {}
virtual Matrix& operator+(Matrix& other)
{
MatrixRegular* regular = dynamic_cast<MatrixRegular*>(&other);
// TODO
}
};
Also, here is another SO thread dealing with the problem of overloading operators from abstract classes.

C++ overloading operator+ for matrixes

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;
}
Is this the correct way to overload arithmetic operators?
Are there memory leaks in my code?
The constructor allocates memory in heap, first for an array of double pointers, then for each pointer an array of double.
You should be returning the new matrix by value, and passing (at leas one of) the arguments by const reference:
matrix operator+(const matrix& A, const matrix& B);
This means that you should not allocate it dynamically inside the body of the operator.
If you only call public member methods or member operators, then there is no need to declare the non-member operators as friend.
Also note that is is common practice to implement +=, *= etc. as member operators, and then implement the non-members in terms of those:
matrix operator+(matrix A, const matrix& B)
{
return A+=B;
}
As an aside, you have to check that the dimensions of the matrices are correct. With your design it is only possible to do this at run-time. Another approach is to enforce dimensional correctness at compile time by making the matrices class templates:
template <typename T, size_t ROWS, size_t COLS> matrix;
The trade-off is that matrices of different dimensions are different types.
That sort of design will quickly be inefficient. Think of what happens when you do:
matrix D = A + B + C ;
Template meta programming gives you some really nice possibilities to avoid making useless temporaries. Armadillo is a really good implementation of the idea.

How to pass a 2D matrix to function

I am doing an addition of matrices using classes.I have declared a class 'Matrix'.now i need to pass an object of Matrix to a function.how do i do that?
Actually, the best way (IMHO) is to overload operator+(). Thus in your code, you'll need to use only +:
class Matrix {
private:
// Your code
public:
// Your code
friend Matrix operator+(const Matrix &c1, const Matrix &c2);
}
friend Matrix operator+(const Matrix &c1, const Matrix &c2) { <--- passing by reference
// Your code to add matrices
}
int main() {
Matrix A, B;
Matrix C = A + B;
}
In the case of the passing by value Matrix sum(Matrix a, Matrix b), you will need to write a copy constructor if memory for matrix is allocated dynamically.
Passing by pointer Matrix sum(Matrix *a, Matrix *b) is a C style coding, so it is still correct, but not preferable for C++.
Matrix object;
// ...
f(object);
You have quite a few ways to do it.
By Value:
void func (Matrix m);
By Reference:
void func (Matrix& m);
Or By Pointer:
void func (Matrix* m);
Which one you use depends on your needs and semantics of the operation.

virtual Operator overloading

I am making a GVector class that contains will further derive into 3 types i.e
PVector (Pixel Space Vector)
MVector (Meter Space Vector)
RVector (Rendering Space Vector)
class GVector {
public :
eVectorSpace eVS; // Defines which space the vector would be
float x,y; // The x and y values of a 2-Dimensional vector
...
GVector operator+ (const GVector& v) const { return GVector(x+v.x, y+v.y, v.eVS); }
...
};
class MVector {
public :
PVector toPVector() {...}
//Will contain functions to convert the same vector into a different space
};
I want to make it possible to add 2 vectors lying in the same space
MVector operator+ (const MVector& v) const { return MVector(x+v.x, y+v.y); }
Do I need to make the base class function like this ?
virtual GVector* operator+ (const GVector* v) const () = 0;
But I would like to return a vector in the same space as the two adding vectors.
The function of adding the values of the x,y are same for each type of vector.
Is there a way to minimize this into the base class itself ?
Or is there a better approach to adding vectors in the same space and converting them into different spaces ?
If it makes no sense to perform operations on two different children then the operator should not be defined on the parent. Instead a protected helper function can be defined, and then the children should implement the operator separately, delegating to the helper function.
Some code somewhere needs to know how to add two of the vector objects together, but it doesn't actually need to be the vector types themselves. You can define a set of addition operators outside the classes.
MVector operator+(const MVector &left, const MVector &right) {
return MVector(left.x + right.x, left.y + right.y);
}
You can define as many different operator adds like this as you want, so long as the compiler can figure out what the types are without ambiguity. You can even provide implementations that accept a MVector and a GVector.
MVector operator+(const MVector &left, const RVector &right) {
MVector tmp = right.toMVector();
return MVector(left.x + tmp.x, left.y + tmp.y);
}

How to make the compiler choose the non-template version of a method for derived classes?

I'm writing a matrix class (CMatrix), with such derived classes as a 3d vector(CVector) and a rotation matrix(CRotMatrix). My CMatrix object could be multiplied by an another CMatrix-based object or by an any numerical value(scalar).
This code represents the essence of the problem I got:
template<class T> class CMatrix
{
public:
template<class U> const CMatrix& operator=(const CMatrix<U> &inp){return (*this);}
CMatrix& operator*(const CMatrix &inp)
{
cout<<"Multiplication by CMatrix"<<endl;
return (*this);
}
template<class U>
CMatrix& operator*(const U &inp)
{
cout<<"Multiplication by a scalar."<<endl;
return (*this);
}
};
template<class T> class CVector: public CMatrix<T>{};
template<class T> class CRotMatrix: public CMatrix<T>{};
int main()
{
CMatrix<int> foo1;
CMatrix<int> foo2;
CVector<int> dfoo1;
CRotMatrix<int> dfoo2;
foo1 = foo1*foo2; //calls CMatrix method
foo1 = foo1*5; //calls scalar method
foo1 = foo1*dfoo2; //calls scalar method, shoud be CMatrix
foo1 = dfoo2*dfoo1; //calss scalar method, shoud be CMatrix
return 0;
}
The problem is that the compiler prefers the template version of operator*(). Is there any way to make the compiler choose the proper method for derived CMatrix classes in this situation? If I cut off this method
CMatrix& operator*(const U &inp)
The compiler does it in the right way, but the class loses the ability to be multiplied by a scalar. I'm using msvc10. Thank you in advance.
The reason is that the template operator is considered an exact match while the matrix version requires a conversion to parent reference. Thus the compiler pick the template as a better match.
First consider if you really need the child classes that you've created and that they provide the appropriate functionality/overrides.
If you need them then I would solve the problem by making one or both of the operations not an operator. By making operator* do both kinds of multiply you violate the principle of least surprise having it do two wildly different things depending on context. I would suggest named methods for both so it's obvious, but otherwise I would suggest operator* to be matrix math and a function ScalarMultiply to do the single scalar type.
The problem is that the compiler prefers the template version of operator*(). Is there any way to make the compiler choose the proper method for derived CMatrix classes in this situation?
That's because you told it to. Your Multiplication by a scalar method is more generic than is your Multiplication by CMatrix method.
Make your "Multiplication by a scalar" method be what the comment says it is:
CMatrix& operator*(const T & inp)
{
std::cout<<"Multiplication by a scalar."<<std::endl;
return (*this);
}
Addendum
Your template<class U> CMatrix& operator*(const U &inp) is so generic that it matches anything. Multiple by a std::istream: No problem. It prints Multiplication by a scalar. You want your multiplication by a scalar to be restrictive, not a catch-all for any random type.