C++ Overload = operator - c++

I'm not sure why I get the following error when trying to overload the = operator
error: passing ‘const MyCircle’ as ‘this’ argument of ‘double MyCircle::getRadius()’ discards qualifiers|
Code:
#include <iostream>
#define PI 3.14
using namespace std;
class MyCircle
{
public:
MyCircle();
MyCircle(int r);
MyCircle(const MyCircle& c);
void setRadius(double r);
double getRadius();
double getArea();
static void increaseInstanceCount();
static int getInstanceCount();
MyCircle operator=(const MyCircle &);
private:
double radius;
static int instanceCount;
};
int MyCircle::instanceCount = 0;
/**
1. A default constructor, that sets the radius to 0
**/
MyCircle::MyCircle()
{
radius = 0.0;
increaseInstanceCount();
}
/**
2. A one argument costructor that accepts an int and uses it to initialize the radius
**/
MyCircle::MyCircle(int r)
{
radius = r;
increaseInstanceCount();
}
/**
3. A copy constructor that accepts a Circle reference as an argument, and uses it to initialize radius
**/
MyCircle::MyCircle(const MyCircle& c)
{
radius = c.radius;
increaseInstanceCount();
}
void MyCircle::increaseInstanceCount()
{
instanceCount++;
}
int MyCircle::getInstanceCount()
{
return instanceCount;
}
void MyCircle::setRadius(double r)
{
radius = r;
}
double MyCircle::getRadius()
{
return radius;
}
double MyCircle::getArea()
{
return (radius * radius) * PI;
}
//overload = operator
MyCircle MyCircle::operator=(const MyCircle &rhs)
{
if(this == &rhs)
return *this;
radius = rhs.getRadius();
return *this;
}
int main()
{
MyCircle circle;
circle.setRadius(5.4);
MyCircle circle2;
circle2.setRadius(3.0);
MyCircle circle3;
circle3.setRadius(343.3);
cout << "Total instances: " << circle.getInstanceCount() << endl;
return 0;
}

You need to add a const qualifier to the getRadius() method, like
double MyCircle::getRadius() const
{
return radius;
}
this will qualify the method to be called with an const object. You might want to add this qualifier to any methods that don't change member variables, avoiding this type of error.

Because your getRadius() isn't declared const.
Change the declaration of it to:
double getRadius() const;
and change the definition of it to
double MyCircle::getRadius() const
{
return radius;
}
You are calling getRadius() via a const reference. Since you don't currently have the method declared const, you're getting that error.

You should declare and define your getRadius function as const:
double MyCircle::getRadius() const
{
return radius;
}
On a side note, there is no reason for you to define a custom operator= for this class, the default will work fine. Also, if you do define operator=, it should probably return by reference.

getRadius is not a const method, while rhs is const. So a non-const method may alter the contents of the class, while a const method tells the compiler to flag any alterations of the instance as an error.
In this case, you can change getRadius to const by adding the const keyword in the method signature
double MyCircle::getRadius() const
{
return radius;
}

In operator=, rhs is declared const, but radius() is called and not declared const. Const correctness is a pain.
You can either declare radius() const or you can just read the radius instance variable directly, like you do in the copy constructor.

You need to mark getRadius() as a const accessor:
double getRadius() const;
double getArea() const;
...
double MyCircle::getRadius() const
{
return radius;
}
double MyCircle::getArea() const
{
return (radius * radius) * PI;
}

Related

Error: return type 'class Polar' is incomplete, invalid use of type 'polar'

I wanted to use casting operator to cast the Rect class to Polar class,
But i am getting error stating "incomplete type". I am not getting any
error on using pointers instead of the object itself. But I can't return
a pointer to object for the purpose of casting.
#include<iostream>
#include<cmath>
using namespace std;
class Polar;
class Rect{
double x;
double y;
public:
Rect(double xx, double yy): x(xx), y(yy) {}
void display(void){
cout<<x<<endl;
cout<<y<<endl;
}
operator Polar(){//need help regarding this function
return Polar(sqrt(x*x + y*y) , atan(y/x)*(180/3.141));
}
};
class Polar{
double r;
double a;
double x;
double y;
public:
Polar(double rr, double aa){
r=rr;
a=aa*(3.141/180);
x= r* cos(a);
y= r* sin(a);
}
Polar(){
r=0;
a=0;
x=0;
y=0;
}
Polar operator+(Polar right){
Polar temp;
//addition
temp.x= x+ right.x;
temp.y= x+ right.y;
//conversion
temp.r= sqrt(temp.x*temp.x + temp.y*temp.y);
temp.a= atan(temp.y/temp.x)*(180/3.141);
return temp;
}
operator Rect(){
return Rect(x,y);
}
friend ostream & operator <<(ostream &out, Polar a);
double getr(){
return r;
}
double geta(){
return a;
}
};
ostream & operator <<(ostream &out,Polar a){
out<<a.getr()<<", "<<a.geta()<<endl;
return out;
}
int main()
{
Polar a(10.0, 45.0);
Polar b(8.0, 45.0);
Polar result;
//+ operator overloading
result= a+b;
//<< overloading
cout<<result<<endl;
Rect r(18,45);
Polar p(0.2,53);
r=p;//polar to rect conversion
r.display();
return 0;
}
Is there a way I can use object of Polar class inside the Rect class. If
not then how can pointers be used for the purpose of casting.
No, you can't use anything that depends on the definition of Polar inside Rect. Polar hasn't been defined. Instead, change operator Polar() { ... } into a declaration: operator Polar(); and put its definition after Polar:
inline Rect::operator Polar() {
return Polar(sqrt(x*x + y*y) , atan(y/x)*(180/3.141));
}
And, incidentally, this operator is a conversion operator. A cast is one way to ask for a conversion, but it's not the only way.
Oh, also, operator Polar() should be const, since it doesn't modify the object that it's applied to. So operator Polar() const; in the definition of Rect, and inline Rect::operator Polar() const { ... } for the definition.

Operator overloading functions

I am stuck with regards to the 2 non-member, 2 non-friend multiplication and the addition of the operator overloading functions. I am unsure of how to do it. Could someone please assist in helping me to resolve this? Refer to my codes below. Thank you in advance!
Compiler output:
Point.cpp:208:19: error: passing ‘const CS170::Point’ as ‘this’ argument discards qualifiers [-fpermissive]
return other + value;
^~~~~
Point.cpp: In function ‘CS170::Point CS170::
operator*(double, const CS170::Point&)’:
Point.cpp:215:10: error: ‘double CS170::Point::x’ is private within this context
result.x = value * x;
^
Point.cpp:215:22: error: ‘x’ was not declared in this scope
result.x = value * x;
^
Point.cpp:216:10: error: ‘double CS170::Point::y’ is private within this context
result.y = value * y;
^
Point.cpp:216:23: error: ‘y’ was not declared in this scope
result.y = value * y;
Point.h
#include <iostream> // istream, ostream
namespace CS1100
{
class Point
{
public:
// Point(double X, double Y); // Constructors (2)
explicit Point(double x, double y);
Point();
Point operator+(const Point& other)const ;
Point& operator+(double value);
Point operator*(double value) ;
Point operator%(double value);
Point operator-(const Point& other)const ;
Point operator-(double value);
Point operator^(const Point& other);
Point operator+=(double value);
Point& operator+=(const Point& other) ;
Point& operator++();
Point operator++(int);
Point& operator--();
Point operator--(int);
Point& operator-();
// Overloaded operators (14 member functions)
friend std::ostream &operator<<( std::ostream &output, const Point &point );
friend std::istream &operator>>( std::istream &input, Point &point );
// Overloaded operators (2 friend functions)
private:
double x; // The x-coordinate of a Point
double y; // The y-coordinate of a Point
// Helper functions
double DegreesToRadians(double degrees) const;
double RadiansToDegrees(double radians) const;
};
// Point& Add(const Point& other); // Overloaded operators (2 non-member, non-friend functions)
// Point& Multiply(const Point& other);
Point operator+( double value, const Point& other );
Point operator-( double value, const Point& other );
My source code:
///////////////////////////////////////////////////////////////////////////////
// 2 non-members, non-friends (operators)
double operator+( double value, const Point& other )
{
return other + value;
}
double operator*( double value, const Point& other )
{
Point result;
result.x = value * x;
result.y = value * y;
return result;
}
As far as I understand the discussion to the question, the problem is not really the operators themselves, but the number of allowed member functions being limited – and you already have exceeded this limit.
However, you have quite a number of functions that don't need to be members, for instance:
class Point
{
public:
Point operator+(const Point& other) const
{
return Point(x + other.x, y + other.y);
}
};
Make free functions from all these:
class Point { /*...*/ };
Point operator+(Point const& l, Point const& r)
{
return Point(l.getX() + r.getX(), l.getY() + r.getY());
}
Having moved out all these operators like the one shown above, you get away far enough from the limit so that you can introduce the needed getters:
class Point
{
public:
double getX() { return x; };
double getY() { return y; };
};
If you are willing to rename the member variables, e. g. by adding a prefix, you can follow another pattern:
class Point
{
double m_x, m_y;
public:
double x() { return m_x; };
double y() { return m_y; };
void x(double v) { m_x = v; }; // the corresponding setter
// (for illustration, you might not need it)
};
This latter pattern is quite common, too. Advantage is being shorter for skipping the explicit get or set prefix, disadvantage is exactly losing this explicitness... Decide you, which one you prefer. More important than personal preference is consistency, though, so if there's e. g. a company's convention or common practice, follow that one...
Some of your operators will need to remain members, though, these are all those that modify the current object:
class Point
{
public:
Point& operator+=(const Point& other) /* const */ // NEEDS to be non-const
{
x += other.x;
y += other.y;
return *this; // <- very good hint to spot the ones needing to stay members
}
};
If you have a public copy constructor, you can re-use the operator+= for defining the operator+:
class Point
{
public:
Point(Point const& other) : Point(other.x, other.y) { }
};
Point operator+(Point const& x, Point const& y)
{
Point r(x); // or Point(x.x(), x.y()), if you lack such constructor)
r += y;
return r;
}
Actually, you can even spare the explicit copy by accepting one of the parameters by value:
Point operator+(Point x, Point const& y)
// ^ no reference
{
return x += y;
}
The latter rather for illustration, I'd prefer the two references in given case to keep the symmetry of the interface...

Using += operator with float values

I'm trying to implement a operator function to solve the next error :
error: assignment of member 'Animal::weight' in read-only object weight +=amount*(0.02f);
My Animal.cpp function looks like:
void Animal::feed(float amount) const
{
if (type == "sheep"){
amount=amount*(0.02f);
weight+=amount;
}else if (type == "cow"){
weight +=amount*(0.05f);
}else if (type == "pig"){
weight +=amount*(0.1f);
}
return weight;
}
Animal.h (short version):
class Animal
{
public:
Animal(std::string aType, const char *anSex, float aWeight, QDateTime birthday);
float getWeight() const {return weight;};
void setWeight(float value) {weight = value;};
float feed(float amount) const;
void feedAnimal(float amount);
private:
float weight;
};
float operator+=(const float &weight,const float &amount);
Then I implemented a += operator.
float operator+=(const float &weight,const float &amount);
Which is also included then in the .cpp file:
Animal & operator +=(Animal &animal, float amount){
float w = animal.getWeight();
animal.setWeight(w+amount);
}
I worked with a reference so that the weight is update for every animal. So I can call the function feed, and when I want to know the result I do it with the get function:
float getWeight() const {return weight;};
But for some reason I catch the next error :
'float operator+=(const float&, const float&)' must have an argument of class or enumerated type
float operator+=(const float &weight,const float &amount);
Any solutions for this?
For use the feed function I also have a problem. I have my Farm.cpp class where i loop for all the animals in the farm.
void Farm::feedAllAnimals(float amount)
{
for (auto an : animals) {
if(an != nullptr) {
an->feed(amount);
}
}
std::cout << "all animals fed with " << amount << "kg of fodder";
}
And in my .h file I have those functions :
Public:
void feedAllAnimals(float amount);
Private:
std::vector<std::shared_ptr<const Animal>> animals;
My error:
error: passing 'const Animal' as 'this' argument of 'float Animal::feed(float)' discards qualifiers [-fpermissive] an->feed(amount);
^
You declared function feed as a const member function
void feed(float amount) const;
^^^^^
You may not change the object if it is a constant object.
As for operator
float operator+=(const float &weight,const float &amount);
then you may not overload operators for fundamental types.
I think you mean either the following
Animal & operator +=( Animal &animal, float amount);
For example
Animal & operator +=( Animal &animal, float amount)
{
animal.setWeight( animal.getWeight() + amount );
return animal;
}
or an operator declared as a member function within the class like
Animal & operator +=( float amount );
As for the vector then the template parameter must be without qualifier const if you are going to change objects pointed to by the elements of the evctor
std::vector<std::shared_ptr<Animal>> animals;

C++ virtual assignment operator

I am trying to call the assignment operator from the base class (shape) in the derived class (point). I get an unresolved external linker error and I don't understand why. I put "virtual" in front of the base assignment operator and placed the base assignment operator inside of my derived class at the end. Where did I go wrong?
#ifndef SHAPE_H
#define SHAPE_H
#include <iostream>
using namespace std;
namespace Joe
{
namespace CAD
{
class Shape
{
private:
int m_id;
public:
Shape(); //default constructor
~Shape(); //destructor
Shape(const Shape& s); //copy constructor
virtual Shape& operator = (const Shape& source); //assignment operator
string ToString() const; //returns id as a string
friend ostream& operator << (ostream& os, const Shape& sh); //global function that can access private members
int ID() const;
};
inline int Shape::ID() const //retrieve ID of shape
{
return m_id;
}
}
}
#endif
#ifndef POINT_H
#define POINT_H
#include <iostream>
#include "shape.h"
namespace Joe
{
namespace CAD
{
class Point: public Shape
{
private:
double m_x;
double m_y;
public:
Point(); //default constructor
~Point(); //destructor
Point(const Point& pt); //copy constructor
Point(double newX, double newY) //constructor accepting x and y coordinates
{
m_x = newX;
m_y = newY;
std::cout << "Point(" << m_x <<","<< m_y <<")" << std::endl;
}
Point(double val); //constructor accepting one double
void X(double newXval) {m_x = newXval;} //default inline setter
void Y(double newYval) {m_y = newYval;} //default inline setter
double X() const; //getter pre-inline
double Y() const; //getter pre-inline
std::string ToString() const; //returns a string description
//distance functions
double Distance() const; //calculate the distance to the origin (0,0)
double Distance(const Point& p) const; //calculate the distance between two points
//operator overloading
Point operator - () const; //negate the coordinates
Point operator * (double factor) const; //scale the coordinates
Point operator + (const Point& p) const; //add coordinates
bool operator == (const Point& p) const; //equally compare operator
Point& operator = (const Point& source); //assignment operator
Point& operator *= (double factor); //scale the coordinates and assign
friend std::ostream& operator << (std::ostream& os, const Point& p); //send to ostream (friend)
Shape& operator = (const Shape& source); // call assignment operator of base class
};
inline double Point::X() const //normal inline getter
{
return m_x;
}
inline double Point::Y() const //normal inline getter
{
return m_y;
}
}
}
#endif
Shape& Shape::operator = (const Shape& source) //assignment operator
{
if (this == &source) //avoid self-assignment
return *this;
cout << "shape assignment" << endl;
m_id = source.m_id;
return *this;
}
Point& Point::operator = (const Point& source) //assign
{
if (this == &source) //avoid self-assignment
return *this;
m_x = source.m_x;
m_y = source.m_y;
return *this;
}
Your problem is that when you call operator = and pass it a Shape, you are calling to Point::operator=(const Shape&), which you do not define, you only define Shape::operator=(const Shape&) and Point::operator=(const Point&). You need to add Point::operator=(const Shape&), for example like this:
Shape& Point::operator = (const Shape& shape) //assign
{
const Point& source = static_cast<Point&>(shape); // or use dynamic_cast here, if you want to be safe
if (this == &source) //avoid self-assignment
return *this;
m_x = source.m_x;
m_y = source.m_y;
return *this;
}
Your problem might be that you define the class in a namespace, but you define the operators outside that namespace without specifying it. Because of this, the compiler can't connect the definition to the declaration.
Ishamael pointed out that you don't specify what happens when a non-Point Shape is assigned to a Point. This is necessary for a virtual assignment operator; see his answer. But this virtual assignment operator could end up doing a lot of unexpected things, like cutting off parts of objects if the wrong types are assigned to each other.
You don't need the virtualness to ensure that the Shape operator also gets called when Point is assigned. Just call the Shape operator inside the Point operator. Making the operator virtual would actually have the opposite effect; the Point operator would override the Shape operator even if the instance you're calling it with is referred to as a Shape.
Point& Point::operator = (const Point& source) //assign
{
if (this == &source) //avoid self-assignment
return *this;
Shape::operator=(source); // also call the base class operator
m_x = source.m_x;
m_y = source.m_y;
return *this;
}

Transform code from member function to non member function

#include <iostream>
using namespace std;
class family
{
private:
double weight;
double height;
public:
family(double x,double y);
~family();
double getWeight();
double getHeight();
double setWeight();
double setHeight();
bool operator==(const family &)const;
};
bool family::operator ==(const family &b)const
{
return weight==b.weight;
}
family::family(double x, double y)
{
weight = x;
height = y;
}
double family::getWeight()
{
return weight;
}
double family::getHeight()
{
return height;
}
family::~family(){}
int main()
{
family a(70.0,175.2);
family b(68.5,178.2);
if(a==b)
cout << "A is bigger than B" << endl;
else
cout << "A is smaller than B" << endl;
return 0;
}
Above the code, I can implement operator overloading with member function. However, I failed to implement operator overloading with non member function. How should i modify this code b.b
Please help me..
Basically, the only difference between a member function and a non-member function is that it's passed an implicit this pointer as well as any other arguments and it has access to private/protected members. So to transform any member function to a non-member function is to simply factor it out of the class definition. make it a friend of that class and add a parameter that's a reference to that class. Pass in an object of that class when you call it. You can also do a const& of the function.
You can use Friend Function and use objects as parameter of that function like we use in << operator.
we also can use operator without friend function :
bool operator==(const family first, const family second)
{
if(first.getWeight( ) == second.getWeight( )){
return True;
else
return False;
}
class family
{
private:
double weight;
double height;
public:
family( double x, double y );
~family( );
// getters should be const
double getWeight( ) const;
double getHeight( ) const;
double setWeight( );
double setHeight( );
};
// no reason to make it friend of class
// b/c it does not work with private/protected members
bool operator==( const family & first, const family & second );
// better to move into cpp file
bool operator==( const family & first, const family & second )
{
return first.getWeight( ) == second.getWeight( );
}