Assignment operator overloading - c++

I was trying to overload assignment operator. Given
Point p1(1,2,3);
Point p2(1,2,3);
Point p3 = p1 + p2;
Point p4 = 22;
cout<< p4;
Here is my full code:
#include<iostream>
#include <bits/stdc++.h>
using namespace std;
class Point{
private:
int m_x, m_y, m_z;
public:
Point(int x=0, int y = 0, int z = 0):m_x(x), m_y(y), m_z(z)
{
}
friend Point operator+(Point &p1, Point &p2);
friend ostream& operator<<(ostream &out, Point &p);
Point operator=(int val);
};
Point operator+(Point &p1, Point &p2){
return Point(p1.m_x+p2.m_x , p1.m_y+ p2.m_y , p1.m_z+p2.m_z);
}
ostream& operator<<(ostream &out, Point &p){
out<<"output: "<<p.m_x<<" "<<p.m_y<<" "<< p.m_z<<'\n';
return out;
}
Point Point::operator=(int val){
return Point(val, val, val);
}
int main(){
Point p1(1,2,3);
Point p2(1,2,3);
Point p3 = p1 + p2;
Point p4 = 22;
cout<< p4;
}
I can't insert the value 22 or any value in m_x, m_y ,m_z. How can I solve the line:
Point p4 = 22;

The are 2 different problems here.
Point p4 = 22;
This is not an assignment, it's actually a call to a constructor. Since you declared your constructor that takes 3 ints with default values, it can be called with 1, 2 or 3 values.
So it's equivalent of doing either of these two
Point p4(22, 0, 0);
Point p4(22);
If you want to use the assignment operator you need to write
Point p4;
p4 = 22;
But here we run in to the second problem, your assignment operator creates a new Point and returns it by value. What you want to do is modify the existing one.
Point& Point::operator=(int val){ // Return by reference
m_x = m_y = m_z = val;
return *this;
}

And you don't need to make the + operation a friend function.
using namespace std;
class Point {
public:
Point() {}
Point(int x , int y , int z ) :m_x(x), m_y(y), m_z(z)
{
}
Point& operator+(const Point &p1);
friend ostream& operator<<(ostream &out, Point &p);
Point& operator=(int val);
private:
int m_x, m_y, m_z;
};
Point& Point::operator+(const Point& p1)
{
Point temp;
temp.m_x = this->m_x + p1.m_x;
temp.m_y = this->m_y + p1.m_y;
temp.m_z = this->m_z + p1.m_z;
return temp;
}
ostream& operator<<(ostream &out, Point &p) {
out << "output: " << p.m_x << " " << p.m_y << " " << p.m_z << '\n';
return out;
}
Point& Point::operator=(int val) { // Return by reference
m_x = m_y = m_z = val;
return *this;
}
int main() {
Point p1(1, 2, 3);
Point p2(1, 2, 3);
Point p3 = p1 + p2;
Point p4;
p4 = 22;
cout << p4;
}

Related

Unexpected output when dealing with operator overloading in C++ using

I am attempting to go through a "Circle" structure (basically a binary tree). Each circle has an centerX, centerY, radius, and two leaf nodes. These leaves will either both be null or both be not null. There will never be one null and one not null.
I am using a variety of operator overloading functions. I am attempting to do one with the "," operator but I am having trouble actually getting the function to hit.
Below is the relevant code:
circle.h:
#include <set>
#include <iostream>
using namespace std;
class Circle {
private:
double centerX, centerY, radius;
Circle* c1;
Circle* c2;
public:
static const int PAGE_DIMENSION = 200;
static const int DEFAULT_MAX_RADIUS = 15;
Circle( double x, double y, double radius, Circle* r1, Circle* r2 );
Circle( double x, double y, double radius );
Circle();
int isLeaf() const;
double getCenterX() const;
double getCenterY() const;
double area() const;
double getRadius() const;
Circle* getFirstSubcircle() const;
Circle* getSecondSubcircle() const;
bool operator<( Circle& other );
Circle* operator()( double x_in, double y_in);
Circle& operator=( Circle& rhs);
Circle* operator,( Circle& other );
double distance( Circle& rhs );
// THESE FUNCTIONS ARE NOT CLASS MEMBERS
// THEY ARE DEFINED OUTSIDE OF THE CLASS
// BUT REQUIRE ACCESS TO PRIVATE FIELDS
friend ostream& operator<<(ostream& osInput, Circle& circle);
friend ostream& operator/(ostream& osInput, Circle& circle);
friend Circle* reduce( set<Circle*>& circles);
};
circle.cpp
#include <math.h>
#include <time.h>
#include <iostream>
#include <algorithm>
#include <stdlib.h>
#include <set>
#include <fstream>
#include "circle.h"
using namespace std;
class CirclePair {
public:
Circle* c1;
Circle* c2;
double distance;
CirclePair(Circle* c1, Circle* c2, double distance)
{
this->c1 = c1;
this->c2 = c2;
this->distance = distance;
}
};
Circle::Circle( double x, double y, double radius, Circle* r1, Circle* r2 )
{
centerX = x;
centerY = y;
this->radius = radius;
c1 = r1;
c2 = r2;
}
Circle::Circle( double x, double y, double radius )
{
centerX = x;
centerY = y;
this->radius = radius;
c1 = NULL;
c2 = NULL;
}
Circle::Circle()
{
unsigned seed = time(0);
srand(seed);
int randomX = rand() % (PAGE_DIMENSION + 1);
int randomY = rand() % (PAGE_DIMENSION + 1);
int randomRadius = rand() % DEFAULT_MAX_RADIUS + 1;
centerX = randomX;
centerY = randomY;
radius = randomRadius;
}
int Circle::isLeaf() const
{
if (c1 == NULL && c2 == NULL) {
return 1;
}
return 0;
}
double Circle::getCenterX() const
{
return centerX;
}
double Circle::getCenterY() const
{
return centerY;
}
double Circle::area() const
{
double pi = 3.14159265358979323846;
return ( pi * (radius * radius));
}
double Circle::getRadius() const
{
return radius;
}
Circle* Circle::getFirstSubcircle() const
{
return c1;
}
Circle* Circle::getSecondSubcircle() const
{
return c2;
}
double Circle::distance( Circle& rhs )
{
double diffX = rhs.getCenterX() - getCenterX();
double diffY = rhs.getCenterY() - getCenterY();
return sqrt((diffX * diffX) + (diffY * diffY));
}
bool Circle::operator<( Circle& other )
{
cout << "Made it to operator <\n";
return area() < other.area();
}
Circle* Circle::operator()( double x_in, double y_in)
{
Circle* c = new Circle();
return c;
}
Circle& Circle::operator=( Circle& rhs)
{
cout << "Made it to operator =";
Circle* c = new Circle();
return *c;
}
Circle* Circle::operator,( Circle& other )
{
cout << "Made it to operator ,";
double distanceBetween = distance(other);
double c3Radius, c3CenterX, c3CenterY;
Circle* c3;
if (distanceBetween + getRadius() <= other.getRadius())
{
c3Radius = other.getRadius();
c3CenterX = other.getCenterX();
c3CenterY = other.getCenterY();
}
else
{
double theta = 0.5 + ((other.getRadius() - getRadius()) / (2 * distanceBetween));
c3Radius = (distanceBetween + getRadius() + other.getRadius()) / 2;
c3CenterX = ((1 - theta) * getCenterX() + theta * other.getCenterX());
c3CenterY = ((1 - theta) * getCenterY() + theta * other.getCenterY());
}
c3 = new Circle(c3CenterX, c3CenterY, c3Radius, this, &other);
return c3;
}
ostream& operator<<(ostream& osInput, Circle& circle)
{
osInput << "[ " << circle.centerX << ", " << circle.centerY << ", " << circle.radius << " ]\n";
return osInput;
}
ostream& operator/(ostream& osInput, Circle& circle)
{
if (circle.isLeaf()) {
osInput << " <circle cx=\"" << circle.centerX << "\" cy=\"" << circle.centerY <<"\" radius=\"" << circle.radius << "\" style=\"fill:blue;stroke:black;stroke-width:.05;fill-opacity:.1;stroke-opacity:.9\"/>\n";
}
else {
osInput << " <circle cx=\"" << circle.centerX << "\" cy=\"" << circle.centerY <<"\" radius=\"" << circle.radius << "\" style=\"fill:yellow;stroke:black;stroke-width:.05;fill-opacity:.0;stroke-opacity:.5\"/>\n";
Circle* firstCircle = circle.getFirstSubcircle();
Circle* secondCircle = circle.getSecondSubcircle();
osInput / *firstCircle;
osInput / *secondCircle;
}
}
Circle* reduce( set<Circle*>& circles)
{
Circle* removeCirc1, removeCirc2;
//while (circles.size() != 1)
//{
std::set<Circle*>::iterator circlesIterator = circles.begin();
std::set<Circle*>::iterator circlesIterator2 = circles.begin();
std::set<CirclePair*> setOfCirclePairs = {};
while (circlesIterator != circles.end())
{
Circle *current = *circlesIterator;
while (circlesIterator2 != circles.end())
{
Circle *current2 = *circlesIterator2;
if (current != current2)
{
CirclePair *currentPair = new CirclePair(current, current2, current->distance(*current2));
setOfCirclePairs.insert(currentPair);
bool testBool = *current2 < *current;
cout << testBool << "\n";
Circle* newC = *current , *current2;
}
circlesIterator2++;
}
circlesIterator++;
}
CirclePair* minDistancePair = NULL;
std::set<CirclePair*>::iterator circlePairs = setOfCirclePairs.begin();
while (circlePairs != setOfCirclePairs.end()) {
CirclePair *currentCP = *circlePairs;
if (minDistancePair == NULL)
{
minDistancePair = currentCP;
}
else
{
if (currentCP->distance <= minDistancePair->distance)
{
minDistancePair = currentCP;
}
}
cout << currentCP->c1->getCenterX() << " " << currentCP->c2->getCenterX() << " " << currentCP->distance << "\n";
circlePairs++;
}
//find lowest distance pair
cout << minDistancePair->distance << "\n";
//}
}
test.cpp:
#include <iostream>
#include <fstream>
#include <set>
#include <string>
#include <stdlib.h>
#include "circle.h"
using namespace std;
int main( int argc, char** argv ) {
Circle* circ = new Circle();
Circle* circ2_1 = new Circle(1, 2, 4);
Circle* circ2_2 = new Circle(134, 55, 3);
Circle* circ2 = new Circle(11, 21, 8, circ2_1, circ2_2);
Circle* circ3 = new Circle(145, 123, 8);
std::set<Circle*> setOfCircles { circ, circ2, circ3 };
Circle* completedCircle = reduce(setOfCircles);
}
The reduce function that is called within tests.cpp is where the code should be getting activated for the "," operation. The function is called "Circle* reduce( set<Circle*>& circles)" within the circle.cpp file. In this function, the following chunk of code is where some calls are made to the operator functions:
if (current != current2)
{
CirclePair *currentPair = new CirclePair(current, current2, current->distance(*current2));
setOfCirclePairs.insert(currentPair);
bool testBool = *current2 < *current;
cout << testBool << "\n";
Circle* newC = *current , *current2;
}
The testBool that is returned from using the "<" works correctly and triggers the "bool Circle::operator<( Circle& other )" function, but the "newC" circle assignment that is not working and the "Circle* Circle::operator,( Circle& other )" function is never being called. This confuses me as I am calling them both in the same fashion.
Any ideas on how to properly call the "," circle operator?
Operator , has lowest precedence of all, and therefore is the worst operator to be used in this manner: https://en.cppreference.com/w/cpp/language/operator_precedence
Since operator = actually has higher precedence, the effect of the problem line is closer to something like:
(Circle* newC = *current) , *current2;
But this won't trigger the overload as the left hand is now a pointer.
To achieve the desired effect you probably need to put braces around the pair:
Circle* newC = ( *current , *current2 );
The answer by Marc is correct: however I am going to recommend that the solution you should be looking for is don't overload operator,. I'm also going to recommend that you also don't overload operator< or operator() for your class, and that you don't overload operator/ for the ostream class.
On of the first question you should ask yourself when writing code is "what does it look like my code is trying to do?" Excessive use of operator overloading generally obfuscates the idea behind the code unless used very sparingly, e.g. even with your operator< function it isn't going to be immediately obvious that it compares the area of the circles. The operator() is also very confusing - I know you probably haven't implemented it yet but it seems like your gearing up to make a function which constructs a new circle; this is not going to be intuitive to anyone who reads it and has to guess what the difference between Circle c(x,y,r) and a subsequent c(x1,y1) is.
Overloading operators for the ostream class is a convention: << streams things 'to' the class and >> streams things 'from' the class. Trying to read code which has ostream / object is going to cause (almost) anyone who looks at it to do a double take.
Another problem, which you have already run into, is that operators have precedence which can lead to weird effects. With function calls, you know that the operands aren't going to magically disappear into operands of a different nearby function.
This is not a rant against you personally, and I have been guilty of thinking 'this would look much nicer if I just overloaded XYZ operator' myself as I am sure many people here have too, but taking a step back and realising that it actually makes the code much harder for other people to read is really important when writing code - especially C++ which has so many other interesting ways of tripping us up.

Why use a reference when returning an ostream class?

The full code looks like this:
#include<iostream>
#include<vector>
#include<string>
using namespace std;
class Point {
double x;
double y;
public:
Point();
Point(int x, int y);
void setPoint(int x, int y);
int getX(void)const;
int getY(void)const;
Point operator + (const Point & point);
Point& operator=(const Point& point);
};
ostream& operator<<(ostream& os, const Point& point) {
os << point.getX() << " ," << point.getY();
return os;
}
Point::Point() {
x = y = 0;
}
Point::Point(int x, int y) {
this->x = x;
this->y = y;
}
void Point::setPoint(int x, int y) {
this->x = x;
this->y = y;
}
int Point::getX(void)const {
return this->x;
}
int Point::getY(void)const {
return this->y;
}
Point Point::operator+(const Point& point) {
Point result(this->x + point.getX(), this->y + point.getY());
return result;
}
Point& Point::operator=(const Point& point) {
this->x = point.getX();
this->y = point.getY();
return (*this);
}
int main() {
Point a(1, 2);
cout << a << endl;
}
In the following part
ostream& operator<<(ostream& os, const Point& point) {
os << point.getX() << " ," << point.getY();
return os;
}
If the return type is ostream, a red line appears. I am not sure what the difference between return type is ostream & and ostream. I'd appreciate it if you explained
*For reference, I forgot to return os, so I edited the post
If you would return an ostream then you would have slicing. In case the passed os was an ofstream then the returned ostream would only be the ostream part of the ofstream and not the full ofstream. When returning by reference you don't have slicing and don't lose information about the full type of the stream.
The ostream object cannot be copied as the copy constructor of ostream object is deleted.
That is why one needs to pass the ostream object by reference.
Pro tip: Ever wondered why we need to return ostream& if it was already passed by reference?

Get "Trigger Breakpoint Error at delete" when using template

I'm using visual studio.
I have 3 class.
It's ok when I try to print Rectangle ABCD, but when i push ABCD into Array [rectangle] A and try to print ABCD again, the "wntdll.pdb not loaded" appear and i continue, it's "triggers breakpoint error!!" at delete in ~Rectangle()
I know it's something up to the pointer in class Rectangle but can't firgure out.
`int main(){
Array<Rectangle>A;
Rectangle a;
cout << a; //It's oke
A.PushBack(a); // problem here
cout<<a;
}`
class Point
{
private:
float _x;
float _y;
public:
float GetX() { return _x; }
float GetY() { return _y; }
public:
Point();
Point(float, float);
Point(const Point&);
~Point() {};
public:
string ToString() const;
public:
friend istream& operator>>(istream&, Point*);
friend ostream& operator<<(ostream&, const Point&);
};
Point::Point() {
_x = 1;
_y = 1;
}
Point::Point(float x, float y) {
_x = x;
_y = y;
}
Point::Point(const Point& a) {
_x = a._x;
_y = a._y;
}
string Point::ToString() const{
stringstream out;
out << "( " << _x << "," << _y << " )";
return out.str();
}
istream& operator>>(istream& in, Point* a) {
cout << "Nhap x: ";
in >> a->_x;
cout << "Nhap y: ";
in >> a->_y;
return in;
}
ostream& operator<<(ostream& out, const Point& a)
{
out << a.ToString();
return out;
}
```
class Rectangle
{
private:
Point* _topleft;
Point* _botright;
public:
void Set_topleft(Point tl) { _topleft = &tl; }
Point Get_topleft() { return *_topleft; }
void Set_botright(Point br) { _botright = &br; }
Point Get_botright() { return *_botright; }
public:
Rectangle();
Rectangle(Point*, Point*);
~Rectangle();
public:
string ToString() const;
public:
friend istream& operator>>(istream&, Rectangle&);
friend ostream& operator<<(ostream&, const Rectangle&);
};
Rectangle::Rectangle()
{
_topleft = new Point(0, 2);
_botright = new Point(3, 0);
}
Rectangle::Rectangle(Point* a, Point* b)
{
_topleft = new Point(*a);
_botright = new Point(*b);
}
Rectangle::~Rectangle()
{
delete _topleft;
delete _botright;
}
string Rectangle::ToString() const
{
stringstream out;
out << "A" << *_topleft << "+" << "D" << *_botright;
return out.str();
}
istream& operator>>(istream& in, Rectangle& a)
{
std::cout << "A( x,y ): ";
in >> a._topleft;
std::cout << "D( x,y ): ";
in >> a._botright;
return in;
}
ostream& operator<<(ostream& out, const Rectangle& a)
{
out << a.ToString();
return out;
}
```
template<class T>
class Array
{
private:
T* _a;
int _len;
public:
Array();
~Array();
public:
int length() { return _len; }
void PushBack(T);
T GetAt(int);
};
template<class T>
Array<T>::Array() {
_a = new T[128];
_len = 0;
}
template<class T>
Array<T>::~Array() {
delete[] _a;
_len = 0;
}
template<class T>
void Array<T>::PushBack(T value) {
if (_len >= 128)
{
std::cout << "Array is over size, which is 128\n";
return;
}
_a[_len] = value;
_len++;
}
template<class T>
T Array<T>::GetAt(int pos) {
return _a[pos];
}
```
The problem in your code is that when you PushBack the Rectangle object a into the array, you create copy of this object. This means that you just copy pointers _topleft and _botright. So in this part of code, you have 2 objects with the same pointers, so you're trying to delete twice the same part of memory.
To fix this you need to define own copy constructor, which will create new pointers in the new object.
Remember also to define own move constructors or make it disable for your class.
Rectangle(const Rectangle &other)
{
if(other._topleft)
_topleft= new Point(*other._topleft);
else
_topleft = nullptr;
if(other._botright)
_botright= new Point(*other._botright);
else
_topleft = nullptr;
}
The next problem is because of definition of void Array<T>::PushBack(T value). Please change it to the void Array<T>::PushBack(const T& value).
Also, try Rectangle(Rectangle&& o) = delete;

Implementing objects from one class in another

I've been having trouble trying to implement objects from class Cart_Vector in class Cart_Point. My compiler has been listing the following errors and I can't seem to fix them:
friend Cart_Point operator+(const Cart_Point&p1,const Cart_Vector&v1);
'Cart_Vector' does not name a type
Cart_Point operator+(const Cart_Point&p1, const Cart_Vector&v1)
'Cart_Vector' does not have a type
x = p1.x + v1.x; request for member 'x' in 'v1', which is of non-class
type 'const int'
y = p1.y + v1.y; request for member 'y' in 'v1', which is of non-class
type 'const int'
return Cart_Vector(x,y); 'Cart_Vector' was not declared in this scope
#include <iostream>
#include <math.h>
using namespace std;
class Cart_Point
{
public:
double x;
double y;
friend class Cart_Vector;
Cart_Point (double inputx, double inputy);
friend Cart_Point operator<<(const Cart_Point&p1, const Cart_Point&p2);
friend Cart_Point operator+(const Cart_Point&p1,const Cart_Vector&v1);
friend Cart_Point operator-(const Cart_Point&p1,const Cart_Point&p2);
double Cart_distance(Cart_Point, Cart_Point);
};
Cart_Point::Cart_Point(double inputx, double inputy)
{
x = inputx;
y = inputy;
}
double Cart_Point::Cart_distance(Cart_Point p1, Cart_Point p2)
{
double distance = (sqrt( pow(p1.x - p2.x,2) + pow(p1.y - p2.y,2) ));
return distance;
//returns distance between p1 (point 1) and p2 (point 2)
}
Cart_Point operator<<(const Cart_Point&p1, const Cart_Point&p2)
{
cout << "p1:(" << p1.x << ", " << p1.y << ")" << endl;
cout << "p2:(" << p2.x << ", " << p2.y << ")" << endl;
return p1,p2;
//this function should just print each point
}
Cart_Point operator+(const Cart_Point&p1, const Cart_Vector&v1)
{
double x,y;
x = p1.x + v1.x;
y = p1.y + v1.y;
return Cart_Point(x,y);
//this function should make a new Cart_Point
}
Cart_Point operator-(const Cart_Point&p1, const Cart_Point&p2)
{
double x,y;
x = p1.x- p2.x;
y = p1.y - p2.y;
return Cart_Vector(x,y);
//this function should make a new Cart_Vector
}
class Cart_Vector
{
public:
double x; //x displacement of vector
double y; //y displacement of vector
Cart_Vector(double inputx, double inputy);
friend Cart_Vector operator*(const Cart_Vector&v1, double d);
friend Cart_Vector operator/(const Cart_Vector&v1, double d);
Cart_Vector operator<<(const Cart_Vector&v1);
friend class Cart_Point;
};
Cart_Vector::Cart_Vector(double inputx, double inputy)
{
x = inputx;
y = inputy;
}
Cart_Vector operator*(const Cart_Vector&v1, double d)
{
double x,y;
x = v1.x*d;
y = v1.y*d;
return Cart_Vector(x,y);
//this function should make a new Cart_Vector
}
Cart_Vector operator/(const Cart_Vector&v1, double d)
{
double x,y;
if (d == 0)
{
x = v1.x;
y = v1.y;
}
x = v1.x/d;
y = v1.y/d;
return Cart_Vector(x,y);
//this function should make a new Cart_Vector and dividing by zero creates v1
}
Cart_Vector Cart_Vector::operator<<(const Cart_Vector&v1)
{
cout <<"v1: <" << v1.x << ", " << ">" << endl;
return v1;
//this function should just print v1
}
//TestCheckpoint1.cpp file below
int main()
{
//I haven't finished the main function to test all the functions yet
return 0;
}
split your code in different files but your implementation of operator << is wrong , consider following code , its just a hint to help
#include <iostream>
#include <math.h>
using namespace std;
class Cart_Vector
{
public:
double x; //x displacement of vector
double y; //y displacement of vector
Cart_Vector(double inputx, double inputy);
friend Cart_Vector operator*(const Cart_Vector&v1, double d);
friend Cart_Vector operator/(const Cart_Vector&v1, double d);
friend std::ostream& operator<<( std::ostream& out,const Cart_Vector&v1);
friend class Cart_Point;
};
Cart_Vector::Cart_Vector(double inputx, double inputy)
{
x = inputx;
y = inputy;
}
Cart_Vector operator*(const Cart_Vector&v1, double d)
{
double x,y;
x = v1.x*d;
y = v1.y*d;
return Cart_Vector(x,y);
//this function should make a new Cart_Vector
}
Cart_Vector operator/(const Cart_Vector&v1, double d)
{
double x,y;
if (d == 0)
{
x = v1.x;
y = v1.y;
}
x = v1.x/d;
y = v1.y/d;
return Cart_Vector(x,y);
//this function should make a new Cart_Vector and dividing by zero creates v1
}
std::ostream& operator<<(std::ostream &out, const Cart_Vector&v1)
{
out <<"v1: <" << v1.x << ", " << ">" << endl;
return out;
//this function should just print v1
}
class Cart_Point
{
public:
double x;
double y;
friend class Cart_Vector;
Cart_Point (double inputx, double inputy);
friend std::ostream& operator<<(std::ostream& out , const Cart_Point&p2);
friend Cart_Point operator+(const Cart_Point&p1,const Cart_Vector&v1);
friend Cart_Point operator-(const Cart_Point&p1,const Cart_Point&p2);
double Cart_distance(Cart_Point, Cart_Point);
};
Cart_Point::Cart_Point(double inputx, double inputy)
{
x = inputx;
y = inputy;
}
double Cart_Point::Cart_distance(Cart_Point p1, Cart_Point p2)
{
double distance = (sqrt( pow(p1.x - p2.x,2) + pow(p1.y - p2.y,2) ));
return distance;
//returns distance between p1 (point 1) and p2 (point 2)
}
std::ostream& operator<<(std::ostream &out, const Cart_Point&p1)
{
// Since operator<< is a friend of the Cart_Point class, we can access Point's members directly.
out << "p:(" << p1.x << ", " << p1.y << ")" << endl;
return out;
//this function should just print each point
}
Cart_Point operator+(const Cart_Point&p1, const Cart_Vector&v1)
{
double x,y;
x = p1.x + v1.x;
y = p1.y + v1.y;
return Cart_Point(x,y);
//this function should make a new Cart_Point
}
Cart_Point operator-(const Cart_Point&p1, const Cart_Point&p2)
{
double x,y;
x = p1.x- p2.x;
y = p1.y - p2.y;
return Cart_Point(x,y);
//this function should make a new Cart_Vector
}
//TestCheckpoint1.cpp file below
int main()
{
Cart_Point point1(2.0, 3.0);
std::cout << point1;
//I haven't finished the main function to test all the functions yet
return 0;
}
Wandbox :
Do yourself a favor and split your code in different files,at least one .h for Cart_Vector, one .h for Cart_Point, and one .cpp for the test script (main). You can correct this code to make it work (just swap the order of the two classes), if you correct other errors too, like in the overloading of the operator "-".
The point here is that if you start coding in this way, when you start programming complex projects you will find yourself in great difficulties. Coding one public (non-inner) class-per file is like applying Single Responsibility Principle for files too. I would say that also a file should have only one reason to change, and this has great benefits in readability and when will you perform version control.
Cart_Vector and Cart_point need each other. So you need to implement these classes in separate header files. Do not forget include them. Also in here ;
Cart_Point operator-(const Cart_Point&p1, const Cart_Point&p2)
{
double x,y;
x = p1.x- p2.x;
y = p1.y - p2.y;
//return Cart_Vector(x,y);
return Cart_Pointer(x,y);
//this function should make a new Cart_Vector
}
You can not access non-const elements of const object and you can not call non-const functions. You can pass these objects by value if you want it.

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