Using += operator with float values - c++

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;

Related

Cannot access public method from another class

I have the following classes:
class Point
{
private:
Vector2d _coordinates;
int _label;
public:
Point(const double x = 0.0, const double y = 0.0);
Point(Vector2d coordinates);
void setCoordinates(const double x, const double y) {_coordinates(x, y);}
const Vector2d& getCoordinates() const {return _coordinates;}
int getPointLabel() const{ return _label;}
void setPointLabel(int label);
class PolygonCutter
{
//output parameters
vector<Point> _newPoints;
vector< vector<Point>> _cuttedPolygons;
public:
void AddLabels(const vector<Point> &points, const vector<const unsigned int>&polygonVertices);
};
I working on PolygonCutter. i need it to be just a manager that uses a methodAddLabels to set the member _label of each Point in vector points to the integers passed as the vector polygonVertices
How can I do it? I am having trouble because I am not able to access the method setPointLabel(int label) from here:
My try contains the following errors:
void AddLabels(const vector<Point> &points, const vector<const unsigned int>&polygonVertices);
{
int originalNumberOfVertices = points.size();
for(int i = 0; i<originalNumberOfVertices ; i++)
{ int label = polygonVertices[i]; // ERROR type 'const vector<const unsigned int>' does not provide a subscript operator
const Point& point = points[i];
point.setPointLabel(label); // ERROR 'this' argument to member function 'setPointLabel' has type 'const Point', but function is not marked const
}
}
in AddLabels method, vector points is const. setPointLabel is non-const member function. non-const member functions can only be invoked for non-const objects. Either
remove const from const vector &points , or
mark function setPointLabel const.

No viable overloaded '=' when assigning an object to another object?

I've tried looking for a solution but the answers in those questions are very specific. Here's what I have.
The header Code.
class InventoryItem {
public:
InventoryItem(char *desc = 0, double c = 0, int u = 0);
~InventoryItem();
char *getDescription() const;
double getCost() const;
int getUnits() const;
void operator= (const InventoryItem &right);
int setUnits;
private:
char *description;
double cost;
int units;
};
The .cpp file associated with the header file.
InventoryItem::InventoryItem(char *desc, double c, int u) {
description = desc;
cost = c;
units = u;
}
InventoryItem::~InventoryItem() {}
void InventoryItem::operator= (const InventoryItem &right) {
units = right.getUnits();
cost = right.getCost();
description = right.getDescription();
}
The CashRegister class.
class CashRegister {
public:
void getItemToPurchase(InventoryItem) const;
private:
InventoryItem item;
}
The error occurs in this code, which is the .cpp file to the CashRegister function.
void CashRegister::getItemToPurchase(InventoryItem item1) const {
item = item1;
}
It says "No viable operator"=" even though item and item1 are both objects of the same class.
I've compared my code to the one in the book but it still doesn't work.
The problem is with const member function in CashRegister. In CashRegister::getItemOnPurchase(), item is a const member. Hence
item = item1;
is not a viable function.
I can think of couple of ways to solve the problem.
Return the object
InventoryItem CashRegister::getItemToPurchase() const {
return item;
}
Return the object as an output argument.
void CashRegister::getItemToPurchase(InventoryItem& item1) const {
item1 = item;
}
Also, it is more idiomatic to return a reference to the object in the operator= function.
InventoryItem& operator= (const InventoryItem &right);

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( );
}

inserting object into set fails

The following class is present:
class Actor {
public:
float xpos{0};
float ypos{0};
Actor(float x, float y);
~Actor();
};
In the a static function of a management class, I want to create such an actor and insert it into a set:
class ActorManager {
private:
ActorManager();
static std::set<Actor> actors;
public:
static void addActor(float x, float y);
}
Definition:
std::set<Actor> ActorManager::actors = std::set<Actor>();
void ActorManager::addActor(float x, float y) {
Actor actor(x, y);
actors.insert(actor); // <--
}
With the marked line present, actors.insert, the compilation fails. The error states:
/usr/lib/c++/v1/__functional_base:56:21: Invalid operands to binary expression ('const Actor' and 'const Actor')
What am I missing here?
You need to overload operator< in order to use your class with std::set (it needs this in order to sort the elements).
bool operator <(const Actor& p1, const Actor& p2){
bool result=false;
if (p1.x<p2.x)
{
result=true;
}
else if (p1.x==p2.x&&p1.y<p2.y){
result=true;
}
return result;
}
//this is the correct way of overloading < operator

C++ Overload = operator

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;
}