C++ Function Overload / With objects - c++

I made a class Valjak (Roller), and gave it variables h (height) and r (radius) and made functions for area (Oplosje) and volume (Volumen).
I created 2 objects and now I need to overload operator + in such way that result of adding two objects from class Valjak (roller) creates a new third object that has as height equal to the height of first object plus the height of second object, and radius that is the radius of first object plus radius of third object.
This is my code so far:
#include <iostream>
#include <math.h>
using namespace std;
class Valjak{
private: float r, h;
public:
Valjak(){
r = 1;
h = 1;
}
Valjak(float rr, float hh){
r = rr;
h = hh;
}
void Oplosje(){
cout << "Oplosje valjka je: " << 2 * (pow(r, 2)*3.14) + 2 * r*h << endl;
}
void Volumen(){
cout << "Volumen je: " << (pow(r, 2)*3.14) * h << endl;
}
};
int main(){
Valjak V1;
Valjak V2(5, 10);
cout << "Vrijednosti prvog objekta!" << endl;
V1.Oplosje();
V1.Volumen();
cout << "Vrijednosti drugog objekta" << endl;
V2.Oplosje();
V2.Volumen();
system("PAUSE");
return 0;
}

First, you must write getters for r and h, let's name them get_r and get_h:
class Valjak {
// ...
public:
float get_r() { return r; }
float get_h() { return h; }
// ...
}
Then overload operator + for two objects of Valjak class:
Valjak operator+(const Valjak & a, const Valjak & b)
{
return Valjak(a.get_r() + b.get_r(), a.get_h() + b.get_h());
}

Related

How here private data members are accessed from the class instance (c++,oops,operator overloading)

#include<iostream>
using namespace std;
class Complex {
private:
int real, imag;
public:
Complex(int r = 0, int i = 0) {real = r; imag = i;}
// This is automatically called when '+' is used with
// between two Complex objects
Complex operator + (Complex const &obj) {
Complex res;
res.real = real + obj.real;
res.imag = imag + obj.imag;
return res;
}
void print() { cout << real << " + i" << imag << '\n'; }
};
int main()
{
Complex c1(10, 5), c2(2, 4);
Complex c3 = c1 + c2;
c3.print();
}
Here operator + is overloaded and it is accesing the private member of res class
Some more examples are
ex1 -
struct Edge {
int a,b,w;
};
bool operator<(const Edge& x, const Edge& y) { return x.w < y.w; }
ex2-
#include <bits/stdc++.h>
using namespace std;
struct Edge {
int a,b,w;
bool operator<(const Edge& y) { return w < y.w; }
};
int main() {
int M = 4;
vector<Edge> v;
for (int i = 0; i < M; ++i) {
int a,b,w; cin >> a >> b >> w;
v.push_back({a,b,w});
}
sort(begin(v),end(v));
for (Edge e: v) cout << e.a << " " << e.b << " " << e.w << "\n";
}
ex1 and ex2 are from the usaco.guide and the first example was from the geeks for geeks
Can anyone explain how it works ?
How here private data members are accessed from the class instance. Can anyone explain how it works ?
First things first, in ex1 and ex2 you're using a struct and so by default every member is public. So any user of the class has access to its members.
Now, even if those data members were private, you've overloaded operator+ and operator< as member functions. And a member function has full access to any(private, public or protected) member of the corresponding class type.

Trying to Understand the behavior of my class objects

Please help me in understanding the following 5 lines of code. What the difference between these two
comp3.AddBoth(comp1, comp2); //this 1 ) give 0 0 but why
comp3.Show();
and
comp3 = comp3.AddBoth(comp1,comp2); //this 2) give 6 + 12i which is the correct answer but why
comp3.Show();
Full code:
#include<iostream>
class ComplexNumber
{
private:
int m_r = 0;
float m_i = 0.0f;
public:
ComplexNumber()
{
}
ComplexNumber(int real, float imagi)
{
m_r = real;
m_i = imagi;
}
void Show()
{
std::cout << " Real and imaginary equation is " << m_r << " + " << m_i << "i " << std::endl << std::endl;
}
ComplexNumber AddBoth( ComplexNumber c1, ComplexNumber c2)
{
int re;
float img;
re = c1.m_r + c2.m_r;
img = c1.m_i + c2.m_i;
ComplexNumber temp(re,img);
return temp;
//std::cout << " Real and imaginary equation is " << re << " + " << img << "i " << std::endl << std::endl;
}
};
int main()
{
ComplexNumber comp1(2, 4), comp2(4, 8), comp3;
comp1.Show();
comp2.Show();
comp3.AddBoth(comp1, comp2); //this 1 ) give 0,0 but why
comp3.Show();
// what the difference between these two
comp3 = comp3.AddBoth(comp1,comp2); //this 2) give 6 + 12i which is the correct answer but why
comp3.Show();
std::cin.get();
//return 0;
}
//#include<iostream>
//
//class ComplexNumber
//{
//
//private:
// int r;
// float i;
//
//public:
// ComplexNumber()
// {
// }
// ComplexNumber(int a, float b)
// {
// r = a;
// i = b;
// }
//
// void Show()
// {
// std::cout << " Real and imaginary equation is " << r << " + " << i << "i " << std::endl << std::endl;
// }
// int getReal()
// {
// return r;
// }
// float getImagi()
// {
// return i;
// }
//
//};
//
//// ComplexNumber here is the return type like int getReal() and flot getImagi
//ComplexNumber AddBothObj(ComplexNumber obj1, ComplexNumber obj2)
//{
// int newR;
// float newI;
//
// newR = obj1.getReal() + obj2.getReal();
// newI = obj1.getImagi() + obj2.getImagi();
//
// ComplexNumber temp(newR, newI);
//
// return temp;
//}
//
//
//int main()
//{
// ComplexNumber comp1(3, 7), comp2(6, 14), comp3;
// comp1.Show();
// comp2.Show();
//
// comp3 = AddBothObj(comp1,comp2);
// comp3.Show();
//
// std::cin.get();
//}
AddBoth is a method of the class ComplexNumber that doesn't modify any instance member, neither m_r nor m_i. What it does is to add two complex numbers and return a new complex number. In the first block you call AddBoth and that call doesn't modify comp3, so you get a (0, 0) output because those happen to be the values to which the members of the instance are initialized to (see private section of the class). In the second block you assign the result of the sum to comp3 and then you print it. That's why you see the expected output.
As pointed out in the comments, in your example, comp3.AddBoth returns a temporary result and doesn't actually modify the current object itself. If you want that behavior you will have to do something like this:
void Add(ComplexNumber other) // you can also make other a const reference which would avoid unnecessary object copies (if the compiler doesn't optimize the copy away)
{
m_r = m_r + other.m_r; // or m_r += other.m_r
m_i = m_i + other.m_i; // or m_i += other.m_i
// if you want to you can also return a reference to the current object here if you
// wish to chain operations like comp3.Add(comp1).Add(comp2)
}
The usage would then be:
// assuming comp1, comp2 are instances of the ComplexNumber class
comp1.Add(comp2); // adds comp2 to comp1, result is "in" comp1
comp1.Show();
If you would rather want to create a new ComplexNumber object from the addition of two other ComplexNumbers you can do:
// notice the static keyword here meaning you don't call this function using an instance of ComplexNumber
static ComplexNumber AddBoth(ComplexNumber c1, ComplexNumber c2) // again you can make c1 and c2 const references
{
int re = c1.m_r + c2.m_r;
float img = c1.m_i + c2.m_i;
ComplexNumber temp(re, img);
return temp;
// or simply return ComplexNumber(c1.m_r + c2.m_r, c1.m_i + c2.m_i);
}
which you would then have to use like this:
// assuming comp1 and comp2 are instances of the ComplexNumber class
ComplexNumber comp3 = ComplexNumber::AddBoth(comp1, comp2); // add comp1 and comp2 and save the result in comp3
comp3.Show();
I think it is obvious that this is an exercise on classes and class objects in C++ but if you want to use complex numbers in real programs I would suggest you have a look at the std::complex data type provided by the C++ standard. I also don't see an obvious reason why the real and imaginary variables should be different data types (int and float).

How to make object of a class with parameterized constructor in other class?

I want to make an object of DataArea class in Area class and initialize data in main function. But the only way my code works is by initializing data in Area class.
Also, I do not know if I have made the object correctly or not. Please guide me. My code is below:
#include<iostream>
using namespace std;
class DataArea
{
public:
int radius, length, width, base, heigth;
DataArea(int l, int w, int b, int h, int r)
{
length = l;
width = w;
radius = r;
heigth = h;
base = b;
}
};
class Area
{
public:
DataArea* s = new DataArea(3, 4, 5, 6, 7);
float AreaCirle()
{
return 3.142 * s->radius * s->radius;
}
float AreaRectangle()
{
return s->length * s->width;
}
float AreaTraingle()
{
return (s->base * s->heigth) / 2;
}
};
class print_data : public Area
{
public:
void print()
{
cout << "Area of Circle is: " << AreaCirle() << endl;
cout << "Area of Rectangle is: " << AreaRectangle() << endl;
cout << "Area of Traingle is: " << AreaTraingle() << endl;
}
};
int main()
{
//DataArea da(3, 4, 5, 6, 7);
print_data m;
m.print();
}
Your DataArea is basically absolute if you do not use it outside of Area class. Similarly, print_data class can be replaced by an operator<< overload.
Following is the updated code, in which the comments will guide you through.
#include <iostream>
// DataArea (optionally) can be the part of Area class
struct DataArea /* final */
{
float length, width, base, height, radius;
DataArea(float l, float w, float b, float h, float r)
: length{ l } // use member initializer lists to initlize the members
, width{ w }
, base{ b }
, height{ h }
, radius{ r }
{}
};
class Area /* final */
{
DataArea mDataArea; // DataArea as member
public:
// provide a constructor which initialize the `DataArea` member
Area(float l, float w, float b, float h, float r)
: mDataArea{ l, w, b, h, r } // member initializer
{}
// camelCase naming for the functions and variables
// mark it as const as the function does not change the member
float areaCirle() const /* noexcept */
{
return 3.142f * mDataArea.radius * mDataArea.radius;
}
float areaRectangle() const /* noexcept */
{
return mDataArea.length * mDataArea.width;
}
float areaTraingle() const /* noexcept */
{
return (mDataArea.base * mDataArea.height) / 2.f;
}
// provide a operator<< for printing the results
friend std::ostream& operator<<(std::ostream& out, const Area& areaObject) /* noexcept */;
};
std::ostream& operator<<(std::ostream& out, const Area& areaObject) /* noexcept */
{
out << "Area of Circle is: " << areaObject.areaCirle() << "\n";
out << "Area of Rectangle is: " << areaObject.areaRectangle() << "\n";
out << "Area of Traingle is: " << areaObject.areaTraingle() << "\n";
return out;
}
int main()
{
// now construct the Area object like this
Area obj{ 3, 4, 5, 6, 7 };
// simply print the result which uses the operator<< overload of the Area class
std::cout << obj;
}
Output:
Area of Circle is: 153.958
Area of Rectangle is: 12
Area of Traingle is: 15
It seems to me that Area class is surplus for what you are trying to achieve. You should probably put methods directly in DataArea class. Then you can create as many of DataArea objects as you like...
Like this:
class DataArea
{
public:
int radius, length, width, base, heigth;
DataArea(int l , int w , int b , int h , int r )
{
length = l;
width = w;
radius = r;
heigth = h;
base = b;
}
float AreaCirle()
{
return 3.142 * radius * radius;
}
float AreaRectangle()
{
return length * width ;
}
float AreaTraingle()
{
return (base * heigth)/2;
}
};
int main(int argc, char **argv)
{
DataArea area1 (1,2,3,4,5);
DataArea area2 (8,2,3,4,5);
std::cout << area1.AreaCirle() << std::endl;
std::cout << area2.AreaCirle() << std::endl;
}
The reason why you are probably having trouble to understand the concept:
You're defining a class and instantiating an object. Sometimes these terms are used interchangeably, but in this case, this is an important distinction.
If you would like for your methods to operate on some other class, that you should make methods that accept that class as an argument. Otherwise, it is unnecessary complex.

c++11 user defined literals for units of physical properties

I am trying to learn how to use c++11 user defined literals for units of physical properties. The question is, how do I avoid a mixing of these units. So that (8.0_kg + 8.0_km)--> gives error. any ideas guys? i am new to c++, be kind.
class Mass{
public:
//Mass(){
// cout << "only Mass units allowed in here" << endl;
//}
//~Mass();
long double getWeight(long double a);
double car, house, cat;
private:
long double a;
};
long double Mass::getWeight(long double w) {
cout << "returning argument: " << w << '\n'<< endl;
return 0;
}
long double operator"" _km(long double d) { return d * 1000.0; }
long double operator"" _m (long double d) {return d;}
long double operator"" _cm(long double d) { return d / 100.0; }
long double operator"" _tonne(long double m) { return m * 1000.0 ; }
long double operator"" _kg(long double m) { return m ; }
long double operator"" _lb(long double m) { return m * 0.453592; }
long double getDistance(long double d){
long double starting_d = 61.0_kg;
long double total_d = d + starting_d;
cout << "the distance I have run is: " << total_d << endl;
return 0;
}
int main() {
cout << 6.0_km << endl;
cout << 6.0_km + 3.0_m << endl;
cout << 6.0_km + 3.0_m + 15.0_cm << '\n' << endl;
cout << 8.0_tonne << endl;
cout << 8.0_km + 4.0_kg << endl;
cout << 8.0_km + 4.0_kg + 21.0_lb << '\n' << endl;
long double distance = 5.45_km;
getDistance(distance);
Mass obj1;
obj1.getWeight(13.96_lb);
cout << "This is clearly wrong: "<< 8.0_km + 4.0_kg << endl;
obj1.getWeight(10.96_km); // so is this
}
You need to define your own types, since you can't restrict what a primitive represents.
You can use a "tagged template"1 to avoid repetition of operators and such and keep it type safe.
This can be extended so you get for instance distance * distance = area or speed * time = distance checked by the compiler.
Here's a short example:
template<typename Kind>
struct Value
{
long double value;
Value& operator+= (Value v) { value += v.value; return *this; }
};
template <typename Kind>
Value<Kind> operator+ (Value<Kind> lhs, Value<Kind> rhs) { return lhs += rhs; }
// These types don't need definitions; we only need some unique type names.
struct M;
struct D;
using Mass = Value<M>;
using Distance = Value<D>;
Mass operator"" _kg(long double d) { return { d };}
Mass operator"" _lb(long double d) { return { d * 0.453592 };}
Distance operator"" _km(long double d) { return { d * 1000 };}
Distance operator"" _mile(long double d) { return { d * 1609 };}
int main()
{
// OK
Distance d = 1.2_km + 0.2_mile;
// OK
Mass m = 2.3_kg + 1.4_lb;
// invalid operands to binary expression ('Distance' (aka 'Value<D>')
// and 'Mass' (aka 'Value<M>'))
Distance d2 = 2.4_km + 1.2_kg; // Nope
}
1) I don't think there's an established term in C++, but it's very similar to what Haskell refers to as phantom types.
Create classes representing numeric values of the different units. That's how it's been done since long before C++ 11.
Custom literals can make instantiation more readable, though, because it helps preserve the usual order of number and unit :)
See http://en.cppreference.com/w/cpp/language/user_literal
class MassKg
{
double value;
// public c'tor, numeric operators, &c.
};
// ...
MassKg mass(5.0);
DistanceM distance(3.0);
auto c = mass * distance; // may yield an instance of TorqueKgM, or MomentumKgM, therefore
// explicit functions / methods are preferrable for mixed
// multiplication or division
auto mass2 = mass + MassKg(2.0); // yiels an instance of MassKg
auto invalid = mass + distance; // compile time error

Return object from class member function in C++

The task is in the above code to write member function that calculate new point, which is amount of two other points. And i dont know how to return object or what should i do. Here is the code, and the function is marked with three !!!. The function must return something, i cant make it void because reference to void is unallowed.
class point {
private:
float x;
float y;
public:
point();
point(float xcoord, float ycoord);
void print();
float dist(point p1, point p2);
!!! float &add(point p1, point p2);
float &X();
float &Y();
~point();
};
float & point::X() { return x; }
float & point::Y() { return y; }
point::point() {
cout << "Creating POINT (0,0)" << endl;
x = y = 0.0;
}
point::point(float xcoord, float ycoord) {
cout << "Creating POINt (" << xcoord << "," << ycoord << ")" << endl;
x = xcoord;
y = ycoord;
}
void point::print() {
cout << "POINT (" << x << "," << y << ")";
}
float point::dist(point p1, point p2) {
return sqrt((p1.x - p2.x)*(p1.x - p2.x) + (p1.y - p2.y)*(p1.y - p2.y));
}
!!!// float & point::add(point p1, point p2) {
point z;
z.X() = p1.X() + p2.X();
z.Y() = p1.Y() + p2.Y();
z.print();
}
point::~point() {
cout << "Deleting ";
print();
cout << endl;
}
int main() {
point a(3, 4), b(10, 4);
cout << "Distance between"; a.print();
cout << " and "; b.print();
cout << " is " << a.dist(a, b) << endl;
}
i make it ! here is what must be add function
//prototype
point &add(point& p1, point& p2);
//function itself
point & point::add(point& p1, point& p2) {
point z;
z.x = p1.X() + p2.X();
z.y = p1.Y() + p2.Y();
z.print();
return z;
}
Many thanks to ForceBru!! and all of you
What to do
You can return a point as well:
point point::add(const point& p1, const point& p2) {
point result;
result.x = p1.x + p2.x;
result.y = p1.y + p2.y;
return result;
}
Note that there's no need to use X() and Y() functions here since this method already has access to the private members.
It's also possible to do an operator overload
/*friend*/ point operator+ (const point& one, const point& two) {
// the code is the same
}
How to use it
int main() {
point one(2,5), two(3,6), three;
three.add(one, two);
std::cout << "Added " << one.print() << " and " << two.print();
std::cout << " and got " << three.print() << std::endl;
return 0;
}
Edit: as it was said in the comments, you shouldn't return a reference to an object created inside your add function since in such a situation you're allowed to return references to class members and to static variables only.
You can use Operator overloading here:
point point::operator+(const point & obj) {
point obj3;
obj3.x = this->x + obj.x;
return obj3;
}
returning object with Addition of two points.
for simple example :
class Addition {
int a;
public:
void SetValue(int x);
int GetValue();
Addition operator+(const Addition & obj1);
};
void Addition::SetValue(int x)
{
a = x;
}
int Addition::GetValue()
{
return a;
}
Addition Addition::operator+(const Addition &obj1)
{
Addition obj3;
obj3.a = this->a + obj1.a;
return obj3;
}
int _tmain(int argc, _TCHAR* argv[])
{
Addition obj1;
int Temp;
std::cout<<"Enter Value for First Object : "<<std::endl;
std::cin>>Temp;
obj1.SetValue(Temp);
Addition obj2;
std::cout<<"Enter Value for Second Object : "<<std::endl;
std::cin>>Temp;
obj2.SetValue(Temp);
Addition obj3;
obj3 = obj1 + obj2;
std::cout<<"Addition of point is "<<obj3.GetValue()<<std::endl;
return 0;
}