Transform code from member function to non member function - c++

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

Related

How do I create a duplicate of an object in C++ when working with classes and objects (Object Oriented Programming)

Create a friend function to duplicate a Shape object. The input parameter of this function will be
a Shape object, and it will return the duplicated object. Use the compare function to show that
the duplication is successful.
In this question, we were supposed to create a "Shape" class and add two private members: length and width (of the type double). Then, compute the area and parameter using those values. Also, we had to create two instances in the main and take user inputs for the values of length and width. All of this must be done using friend functions.
Could anyone please help with the duplication thing?
Okay, so I have compared both objects using the operator==() function. Does it mean that creating a duplicate object is similar to creating a copy constructor?
This is the code that I've written so far:
#include <iostream>
using namespace std;
// all functions need to be friend functions
class Shape {
private:
double length, width;
public:
Shape();
Shape(double length, double width);
friend double area(const Shape &sh3);
friend double perimeter(const Shape &sh3);
friend bool operator==(const Shape &sh1, const Shape &sh2);
friend void Shape(const Shape &sh3, const Shape &sh1, const Shape &sh2);
};
Shape::Shape() {
width = 0.0; length = 0.0;
}
Shape::Shape(double length, double width) {
this->length = length; this->width = width;
}
double area(const Shape &sh3) { // friend fucntion to compute the area!
return (sh3.width*sh3.length);
}
double perimeter(const Shape &sh3) { // friend fucntion to compute the perimeter!
return (2*(sh3.length) + 2*(sh3.width));
}
bool operator==(const Shape &sh1, const Shape &sh2) { // friend function to compare the area of two objects!
if (sh1.length == sh2.length && sh1.width == sh2.width) {
cout << "Both shapes are equal\n";
return true;
}
}
//friend function to create a duplicate of the object:
void Shape(const Shape &sh3, const Shape &sh1, const Shape &sh2) { // calling the copy constructor
class Shape sh4;
if (operator==(sh1, sh2) == true) {
sh4.length = sh3.length;
sh4.width = sh4.width;
}
}
int main () {
double l, w; cout << "Enter the values for shape 1: "; cin >> l >> w;
class Shape sh1(l, w); // onject 2
double l1, w1; cout << "Enter the values for shape 2: "; cin >> l1 >> w1;
class Shape sh2(l1, w1); // object 1
class Shape sh3; // object3 using the preset values for l and w
operator == (sh1, sh2); // to compare both objects
return 0;
}
You're almost there... I'd just like to point out a couple of error in your code.
You can't call your function Shape(), there is a class called Shape, and you cannot declare a friend constructor.
class Shape {
private:
double length, width;
public:
Shape();
Shape(double length, double width);
friend double area(const Shape &sh3);
friend double perimeter(const Shape &sh3);
friend bool operator==(const Shape &sh1, const Shape &sh2);
// friend void Shape(const Shape &sh3, const Shape &sh1, const Shape &sh2);
// since we're going to copy Shapes We might as well define a copy contructor.
Shape(const Shape& other)
{
length = other.length;
/* etc...*/
}
// One friend function that takes in a const ref and returns an object.
friend Shape Duplicate(const Shape& other)
{
return other; // calls the copy constructor
// if no copy constructor, use another construtor to initialize object
return Shape(other.length, other.width);
}
};
// ...
Shape a(1., 2.);
Shape b = Duplicate(a); // spawning a new Shape
if (a == b) // calling operator ==
// do something

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;

overloading operator== comparison 2 class

i'm new in programming and i'm trying to search an element in a list of class and i did this:
string x;
cin >> x;
list<Person>::iterator findIter = std::find(ListPerson.begin(), ListPerson.end(), x);
but it seem like i must overload the operator== to work, i did this:
friend bool operator== (Person &P1, Person &P2);
bool operator== (Person& P1, Person& P2)
{
return (P1.Name == P2.Name);
}
but it doesn't work i got always this error : c2678 binary '==' no operator found which takes a left-hand operand of type Person.
Thank you for helping !
Have you tried declaring the parameters as constant references? A comparison operator does not need to have side-effects.
The following works for me, and prints yeah:
#include <iostream>
using namespace std;
struct P {
const int x;
P(int x) {
this->x = x;
}
};
bool operator== (const P & p1, const P &p2) {
return p1.x == p2.x;
}
int main()
{
P x(0), y(0), z(1);
if (x == y) {
cout << "yeah" << endl;
}
if (y == z) {
cout << "nope" << endl;
}
}
Of course you might need to declare the operator== as a friend function if you want to do a comparison over private instance variables.
class P {
int x;
public:
P(int x) {
this->x = x;
}
friend bool operator== (const P &p1, const P &p2);
};
Your friend bool operator== declaration should be inside the class declaration. Next, pass by const reference instead, as rvalues cannot bind to non-const references and also the std::find expects its compared-to element by const reference. So your operator== should be able to compare const references, and non-const ones will not do since they will discard const qualifiers. To fix, declare
friend bool operator==(const Person &P1, const Person &P2);
Live working example here.

Function returning to ostream

I wonder if there is any possibility to create function returning some part of ostream, like in example:
#include <iostream>
class Point {
public:
Point(int x, int y){
this->x = x;
this->y = y;
}
?? getXY(){ // I wish this function returned ostream
return ??;
}
private:
int x,y;
};
int main() {
Point P(12,7);
std::cout << "(x,y) = " << P.getXY(); // (12, 7);
}
I wish the output was:
(x,y) = (12,7)
I don't want getXY() to return any string or char array. May I somehow return part of stream?
Generally this is done by overloading the stream insertion operator for your class, like this:
class Point {
public:
Point(int x, int y){
this->x = x;
this->y = y;
}
int getX() const {return x;}
int getY() const {return y;}
private:
int x,y;
};
std::ostream& operator<<(std::ostream& out, const Point& p)
{
out << "(x,y) =" << p.getX() << "," << p.getY();
return out;
}
Used as:
Point p;
cout << p;
Why not just implement operator << for your class? It would do exactly what you want.
If you only need to print one sort of output, just override operator<< in your containing class. But, if you need to print different sorts of output according in different contexts, you might try creating objects of different proxy classes.
The proxy object could hold a reference to Point, and print it (or portions of it) according to your needs.
I would make the proxy objects private member classes of Point to restrict their visibility.
EDIT Removed sample -- I didn't notice this was homework.
In addition to your Point code, you can use a helper function (below, display()) as an alternative to overloading:
std::ostream& display(std::ostream &os,Point &p) const {
os<< p.x << p.y ;
return os;
}
int main() {
Point p;
display(std::cout,p);
// This will call the display function and
// display the values of x and y on screen.
} //main
The display function can be made a friend of class Point if it needs to access private members.

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