use of std:swap (in implementation of assignment operator) - c++

I have seen in some place an implementation of assignemt operator of class matrix looks like this:
class Matrix
{
private:
int rows;
int cols;
int **mat;
public:
Matrix& operator=(const Matrix& m)
{
if ( this != &m )
{
Matrix temp(m);
std::swap(temp.rows, rows);
std::swap(temp.cols, cols);
std::swap(temp.mat, mat);
}
return *this;
}
}
Now, suppose I want to use swap function for that matter , what is the alternative way to use it without writing std:swap? Am I suppose in such case to build a friend-function that implementing swap of two matrix?

Now, suppose I want to use swap function for that matter , what is the alternative way to use it without writing std:swap? Am I suppose in such case to build a friend-function that implementing swap of two matrix?
You have to swap the two Matrix objects. Whether you do it in the operator= function or another function is secondary.
As a matter of practice, I would recommend creating a function that swaps two Matrix objects and use it the implementation of the operator= function. You have various options for that.
Make it a non-member friend function.
Make it a static member function.
Make it a non-static member function.
I would probably pick a static member function but I don't see any downsides to using one of the other two.
One thing to note is that you will end up using std::swap to swap the member variables of the Matrix objects in that function. It came across to me as though that is a concern for you.

Related

Is this way of abstracting template Matrix class data type good?

I recently had to write my own matrix multiplication library. Initially, I wrote it as a template class then I realized that most classes use the matrix class without caring about the datatype used by Matrix class because they just perform a certain transformation and to the matrix without checking the result. So they really ought to not be aware of the datatypes. I was thinking of making a matrix class with a void pointer to the data.
class Mat
{
private:
void *data;
int dtype; // data type used by matrix
int cols, rows;
template<class type>
Mat add(const Mat& a, type unused); // notice unused parameters
public:
Mat(int dtype);
~Mat();
Mat operator+(const Mat& a);
template<class type>
type* getdata(); // this only function that exposes the
//datatype to the user since they want to read the elements
};
I need a the addition function to be a template since its accelerating computations using SSE intrinsics and I have abstracted the intrinsics using template classes. So I thought of adding an unused parameter to the template add so that the compiler would be able to distinguish between the different templates.
Mat Mat::operator+(const Mat& a)
{
Mat result;
switch(dtype)
{
case 0: // int
result = this->add<int>(a, 0);
break;
case 1: // float
result = this->add<float>(a, 0);
break;
};
return result;
}
Is this a bad idea ? if not any way to get rid of the unused parameter in the add method ?
Another Idea I had was to Make IntMatrix, Float Matrix classes inherit from Mat class just to have it call the add function with the template type to avoid having the case switch in the operator overload of the addition. Is this also a bad design ?
clarification
I want to be able to have 2 vectors:
vector<Transform*> transformVector; // list of classes doing operation on matrix
vector<Mat*> results; // intermediate results vector
results.push_back(input_mat)
for(int i = 0; i < transformVector.size(); ++i){
results.push_back(transformVector[i]->transform(results[i]));
// transform here might have to return a result of type float
// even though the input was of type int
}
It would be more efficient to make the Mat class templated and let the compiler create the necessary add functions.
With the current implementation, you'd have to add a new switch case for each new type, and be careful to properly cast the void* to the right type. When you use templates, the compiler will helps you out by checking your types.
You could even create a template which lets you add a Mat<int> to a Mat<float> (or two other matrices of different types).
template <typename T, size_t Col, size_t Row>
Mat {
std::array<T, Col * Row> data; // or other data structure
// ...
template <typename OtherT>
add(const Mat<OtherT, Col, Row>& other);
};
One hard point here is type * getData().
Here again, either you return a plain void * and require the caller to do an explicit cast on it, or you have to use a templated function.
Long story made short, you have changed a templated class (where the overload are resolved at compile time) for a bunch of template methods and a bit of switches to resolve some of the functions at run time.
You say most classes use the matrix class without caring about the datatype. That is exactly what templates are made for: a bunch of storage and processing that is independant of the underlying type (well templates can do a little more, but were initialy created for that)
void * is always a safe pointer and is a great choice for C compatible APIs. But unless you have performance problems (templates can use too much memory on tiny systems because they declare a different class for each implementation (*)), and can prove that a void * is better for a specific use case, you should stick to the common rules. Write simple and easy to read code, and only optimize when you have found a bottleneck.
After your edit, I can see that you want to store matrixes of different underlying types in a single container. I can imagine polymorphism if all matrixes can derive from a common non templated type but I would not be surprised if you suddenly fall in the type * getData() problem later: you static cast a void pointer, so the compiler has no way to prevent you to do a bad cast. An other possibility would be std::variant on matrixes (if C++17) or boost::variant or any other variant or any alternative. Some of them implement tricks for preventing bad casts at run time.
Hard to know which way is best without experimenting over the real problem...
Some other languages like Java have not templates (a different class for each and every implementation) but generics (a common class that acts on objects). The pros is only one class so the question about the correct template not being available at link time has vanished, the cons is that it requires some tricks to make the actual type available at run time.

Comparing data between two objects of a class

So, I've created a class and then construct two separate instances of that class:
disc discOne; // Construct objects
disc discTwo;
The declaration of the class is done separately through a header file:
class disc
{
public:
disc();
~disc();
void changeRadius(short);
void throwDisc(short, short);
void printLocation() const;
void printInfo() const;
private:
short radius;
short xlocation;
short ylocation;
};
I can use the printInfo() and changeRadius() functions for example, but how can I compare (for example) the radius between these two objects? I want to do something more complex than this, but if I understand the basics I want to try and figure it out.
The problem I'm running in to is that I've used structures in the past, which (if this was the case), I would simply go:
discOne.radius > discTwo.radius
Or something similar. But, that syntax for classes calls a function tied to that class. Sorry for the rambling, but I'm having trouble articulating it - probably why I've struggled to find any guidance through my own searches on the internet.
Three ways:
Use a getter method getRadius() const {return radius;}
and just compare as you always did.
Use overload for operator< and operator> if you want to compare two objects directly (but this doesn't seems the right case.
Declare a friend function bool compareRadius(const Disc& discOne, const Disc& discTwo) to perform the comparison without involving directly the objects.
Of course the simpliest way is the first. I just showed some other option you could consider for similar problems.
Edit: Answer #3 is based on Scott Meyer's Effective C++, item 23 (though it specifies non-friend).
You could add a "getter" to your class (like short getRadius() const) through which you can obtain a value to compare: discOne.getRadius() < discTwo.getRadius().
Alternatively you could add a operator< overload to disc itself, and have it perform the comparison between radii. However, this only makes sense if the radius is the only property of the disc (which it isn't — you have location also), and if comparing radii is equivalent to comparing discs (and I'm not convinced that this would be logical).
Beyond that there are all sorts of clumsy solutions, like adding a bool radiusIsLesserThatThisOtherDiscsRadius(const disc& otherDisc) const member function.
But, that syntax for classes calls a function tied to that class
Actually, that's not true; C++ does not have "structures", so struct introduces a class too, and discOne.radius > discTwo.radius would have worked just fine here if radius were not a private data member. But it being a private data member is appropriate.
struct disc
{
public:
disc();
~disc();
void changeRadius(short);
void throwDisc(short, short);
void printLocation() const;
void printInfo() const;
private:
short radius;
short xlocation;
short ylocation;
};
// ^ Exactly the same thing; your approach still won't work, for the same reason
Simple solution to overload the > operator on objects like below to compare radius of two objects of the class.
discOne > discTwo;
you can overload > according to your requirement, Here is the simple one
bool disc :: operator > (disc my_disc)
{
if(radius > my_disc.radius)
return true;
else
return false;
}
Above one is one of the solution to solve your problem. There are other ways by which you can compare two objects as suggested by others. Use separate member function( or friend function) to do the same task.

Best way to return an inherited class from a function in c++

I'm looking for advice as to how to proceed with this class hierarchy I'm building in C++.
Base class is Matrix:
class Matrix
{
protected:
int rows;
int columns;
double* values;
public:
\\lots of stuff goes here. bla di bla di bla.
virtual Matrix operator+(const Matrix& addend) const;
\\etc.
}
Squarematrix is inherited from Matrix
class Squarematrix : public Matrix
{
public:
Squarematrix operator+(const Squarematrix& addend) const;
}
Operator+ returns a matrix or a squarematrix respectively. Since operator+ is a virtual function this wont compile, as it must have the same return type in all classes.
So what are my options?
I could use an ordinary function instead of virtual. This is a bit annoying, but wouldn't cause a problem under most circumstances.
I could return a matrix in all cases. This would basically make my squarematrix class a right pain in the *** to use, as I would have to constantly downcast from matrix to squarematrix.
I could return a reference to a squarematrix. Then the matrix would have to be stored on the heap and there's no way to make sure its deleted safely. Especially if I do something like this:
squarematrix a=b+(c+d);
(c+d) will be stored on the heap and have no pointer to it so will be leaked.
Is there any way to keep virtual functions and still have different return types?
What would you advise in this situation?
Thanks for your help. Looking forward to hearing from you.
I would recommend:
Remove Squarematrix.
Add a constructor to Matrix to construct a square matrix.
If the knowledge of whether a matrix is square matrix is helpful for your application, add a member function in Matrix to answer that query.
class Matrix
{
public:
Matrix(int r); // Construct a square matrix.
Matrix(int r, int c); // Construct a rectangular matrix.
bool isSquareMatrix() const { return (rows == columns); }
Matrix operator+(const Matrix& addend) const;
private:
int rows;
int columns;
double* values;
}
This is known as return type covariance (https://en.wikipedia.org/wiki/Covariant_return_type).
It was not supported by old compilers, but is supported by many now. For example my code compiles fine in Visual Studio 2017. Here is an article on its use and limitations in c++: https://aycchen.wordpress.com/2009/08/17/covariant-return-type-in-cpp/.
It is not supported in C# yet, but is being considered for a future version. See https://github.com/dotnet/csharplang/issues/49.
It is also supported by newer versions of Java. See https://blogs.oracle.com/sundararajan/covariant-return-types-in-java.
Other than implementation issues, as far as I know there is no reason for it not to be added to a polymorphic language. I don't believe it can cause errors, although due to an imperfect implementation in Java it can cause bugs-see https://dzone.com/articles/covariant-return-type-abyssal.

Implementation of methods of interface

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.
For that, I'm using the strategy pattern, where I create the base abstract class Matrix, two classes that inherit from Matrix - RegMatrix and SparseMatrix, and MyMatrix that holds a pointer to a Matrix.
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.
so I have 2 questions:
The only hint I have is to create an iterator of type "matrix", and implement the iterator for each type of matrix (regular and sparse).
how can I do such a thing?
Let's say I implemented an iterator for both types of "matrix". how can I use the different iterators, in case I have to add two different types of matrices? do I have to implement all 4 different cases?
The operator+ looks like:
Matrix& operator+(const Matrix& other)
{
.....
}
Prefer not to implement the functionality in the base class.
Implement the functionality in each of the child classes. This will allow for use of optimal algorithms.
Or you could declare getters and setters as abstract in the Base class and use them in your base class implementation:
struct Matrix_Base
{
virtual int get_value(unsigned int row, unsigned int column) = 0;
virtual void set_value(int value, unsigned int row, unsigned int column) = 0;
Matrix_Base operator+(const Matrix_Base& other)
{
// perform addition
int sum = get_value(row, column) + other.get_value(column, row);
set_value(sum, row, column);
//...
}
};
Remember, when passing a Matrix, the receiving function can only use common functions (interface) of the Matrix. For specifics, functions will have to use specialized (descendants) in the parameter lists.
You may implement + operator only for RegMatrix and 2 conversion operators:
1. From RegMatrix to SparseMatrix
2. From SparseMatrix to RegMatrix
What are performance requirements?

Designing an object in C++ that can be compared in multiple ways

Suppose we have an object which represent a box.
class Box {
public:
int length;
int width;
int height;
Box(int l, int w, int h);
~Box();
int area(const int l, const int w) const;
int volume(const int l, const int w, const int h) const;
};
Now lets say in another class, in another file, we have an std::list<Box> that contains n boxes. We want to display a print out of these boxes in different ways.
First we want to print them out in order of increasing size by their lengths.
Then we want to print them out in order of increasing size by their widths.
We don't care about their heights right now, but maybe later we will.
Now std::list has a member function sort() that takes a comparison function as an argument. How can we alter the above Box class so that we can call sort() on our list with different comparison functions?
More specifically, can we define three different functions inside the box class and simply pass them to list.sort()? Is it better to define the comparison functions globally outside of the class Intuitively, tying them to the class seems better but why would this not be the case? Overall, what is the "best" way to achieve this?
If you really want to implement the three different comparison
operations as members you can do something like this:
struct Box {
int x, y, length;
bool less_by_x(const Box& other) { return this.x < other.x; }
bool less_by_y(const Box& other) { return this.y < other.y; }
bool less_by_length(const Box& other) { return this.y < other.y; }
};
and use them like this:
#include <functional>
// you probably shouldn't be using a list anyway
std::list<Box> l;
l.sort(std::mem_fun_ref(&Box::less_by_x));
mem_fun_ref returns an binary function object that takes a reference to the class of which the function is a member and all the rest of the arguments (only in C++11, this is limited to binary functions in C++03) of the member functions.
Although it seems much more reasonable to implement the comparison
operations as free functions.
You have to provide a comparator function (or a function object). For example:
bool my_sort_function (const Box& box1, const Box& box2)
{
// use some criteria and return a boolean (true if box1 goes before box2)
// ...
}
Then invoke the sort () method in the following way:
my_list.sort (my_sort_function);
std::list::sort() accepts a comparison function object, which lets you define custom sort criteria. This can be a normal function (free function or static member) or an instance of a class with a compatible operator(). See some documentation for details and an example.
The various sorting functions in the standard C++ library take comparision objects. These may contain whatever data they need. The key requirements they have is that they are copyable and that their function call operator yields a strickt weak order when applied to objects of their argument type. It is easy to create a comparison object which e.g. stores a pointer to member function used to map an object to an attribute, especially if all the attributes have the same type (if the attributes have different types things are bit more interesting). With this it is rather straight forward to sort the same list into different orders.
The best way to do this is to implement a comparison function for each parameter and pass that to sort when calling the sort.
That function boolean comparison(Box a, Box b) should be equivalent to a < b, that is, it is true if a comes before b when sorting by that parameter.
If you want to pass member functions as parameters then your best option is to use boost::mem_fn