how to use +operator proper in object combinining? - c++

class Point {
private:
float xcord;
float ycord; }
class Line{
friend class Nonlinear;
protected:
float dist;
Point *p1,*p2;
virtual const Line& operator+(const Line& l) const;
for virtual operator+ how can i update the new p1 and p2 values of newly created object?
i can update the dist value by using
Line *l1=(Line*)&l
l1->dist=dist+l.dist
but i didnt understand why i am getting stuck on combining Points.

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

No default constructor exists for the class

I know this question has already been ask, but I couldn't figure it out.
I have two classes Point and Line, and 2 Points are members of Line. However in the Line constructor I get "no default constructor exists for the class" error. How can I fix this problem?
#include <cstdlib>
#include <cmath>
#include "PointClass.h"
using namespace std;
class Line {
public:
Line(const Point& p1, const Point& p2) {
this->point1 = p1;
this->point2 = p2;
}
Point point1;
Point point2;
static double Distance(Point p1, Point p2, Point p3) {
double distance = (abs((p1.y - p2.y) * p3.x - (p2.x - p1.x) * p3.y + p2.x * p1.y - p2.x * p1.x) / (sqrt(pow((p2.y - p1.y), 2.0) + pow((p2.x - p1.x), 2.0))));
return distance;
}
};
class Point {
public:
Point(double a, double b) {
this->setCoord(a, b);
}
double x;
double y;
void setCoord(double a, double b)
{
this->x = a;
this->y = b;
}
};
The reason for you error, is that this code calls the Point default constructor (which doesn't exist)
Line(const Point& p1, const Point& p2) {
this->point1 = p1;
this->point2 = p2;
}
instead you should write it like this
Line(const Point& p1, const Point& p2) : point1(p1), point2(p2) {
}
Your version calls the Point default constructor and then assigns the point values. My version initialises the points by calling the Point copy constructor
The error message says "no default constructor", so you should add ones.
class Line {
public:
Line() {} // add this
Line(const Point& p1, const Point& p2) {
class Point {
public:
Point() {} // add this
Point(double a, double b) {
or ones with initialization (safer):
class Line {
public:
Line() : point1(), point2() {} // add this
Line(const Point& p1, const Point& p2) {
class Point {
public:
Point() : x(0), y(0) {} // add this
Point(double a, double b) {
or constructors with default arguments:
The core reason you are getting that error. Is because Line constructor doesn't know how to initialize point1 and point2 prior to your assignment statements in the constructor. That's what constructor initialization lists are for. It's usually better to do initial member initialization in the constructor initialization list instead of in the constructor body. Without a constructor initialization list, point1 and point2 get constructed with the default constructor (error because it's missing) and then immediate updated with additional code in constructor body. You can avoid the need for a default constructor on Point by having Line constructor defined as follows:
Line(const Point& p1, const Point& p2) : point1(p1), point2(p2)
{}
That will resolve your compiler error. Further, it's still not a bad idea to have a default constructor for Point. It's the type of class where it's often useful to have such a constructor. And some point later, you might need to have a collection of Point instances and the compiler will complain again without it. MakeCAT's answer is correct in that regards.
Aside: Your Distance function is passing Point parameters by value. This means the compiler needs to construct 3 new instances of Point each time Distance is invoked. Change your function signature for Distance as follows. If this doesn't make the compiler happy, it will at the very least, generate more efficient code.
static double Distance(const Point& p1, const& Point p2, const& Point p3) {
double distance = (abs((p1.y - p2.y) * p3.x - (p2.x - p1.x) * p3.y + p2.x * p1.y - p2.x * p1.x) / (sqrt(pow((p2.y - p1.y), 2.0) + pow((p2.x - p1.x), 2.0))));
return distance;
}
The problem is that you don't have a default constructor for that class and therefore when you create the points you don't know what values their variables will take.
The easiest and fastest way of solutions is to give default values to the constructor when it does not receive parameters
class Point {
public:
//only modification here
Point(double a = 0, double b = 0) {
this->setCoord(a, b);
}
double x;
double y;
void setCoord(double a, double b)
{
this->x = a;
this->y = b;
}
};
The default constructor is the constructor without parameters. If you have a user provided constructor taking parameters (like your Line constructor taking two Points) then you don't automatically get the default constructor, you need to add it yourself.
I suggest changing your classes
to use in-class initializers
to use member initialization instead of setting in the constructor body
defaulting the default constructor (which requires step 1)
You can compare the IsoCppCoreguidelines for a more detailed explanation on these changes.
class Point {
public:
Point() = default;
Point(double a, double b) : x{a}, y{b} {}
double x{};
double y{};
};
class Line {
public:
Line() = default;
Line(const Point& p1, const Point& p2) : point1{p1}, point2{p2} {}
Point point1{};
Point point2{};
};

returning an object by function without using & (c++) [duplicate]

This question already has answers here:
C++ best practice: Returning reference vs. object
(8 answers)
Closed 5 years ago.
Why do you return an object with function by using &?
For example, lets have a look at the following classes and function:
class Point
{
public:
Point(int x, int y);
int getX() const;
int getY() const;
void setX(int x);
void setY(int y);
void print() const;
private:
int x, y;
};
class Circle
{
public:
Circle(int x, int y, int r, int color);
int getColor() const;
void setColor(int color);
bool contains(const Point &p) const;
void print() const;
private:
const Point center;
int radius, color;
};
class Collection
{
public:
Collection(int radius, int width, int height, int color);
~Collection();
Circle& getCircleAt(const Point &p);
void print() const;
private:
int count;
Circle **circles;
};
Circle& Collection::getCircleAt(const Point &p)
{
for (int i = 0; i < count; i++)
if (circles[i]->contains(p))
return *(circles)[i];
}
The function above returnes a circle.
In the function getCirclet, why is the sign & is necessary ? Why can't I omit it?
In your function
Circle& Collection::getCircleAt(const Point &p)
the return type Circle& means that a reference to on object of type Circle will be returned. If you declared your function
Circle Collection::getCircleAt(const Point &p)
with the same body, then a copy of the object would be returned, if a copy constructor is available. This means in the first case, if you modify the returned object, this will modify the object contained in the Collection, while in the second case, only the copy will be modified.
Note that references cannot be NULL, so you have a problem if your particular function is called with a Point that is not inside any Circle. Returning nothing at all, as you do now, is not an option.

C++ operator overriding w/ arguments from 2 classes

I'm new to object oriented programming and I'm wondering if it's possibile to create an operator for one class which will use arguments from this class and another one, declared by me.
The problem I have to solve is a linear translation on a given point. So I created classes Point and LinearTranslation and basically what I want to do is to create an operator
Point operator* (Point p, LinearTranslation l)
which would take Point p, do the translation l and then return Point. I'm getting weird errors though: Point operator*(int)’ must have an argument of class or enumerated type or that LinearTranslation has not been declared.
Is it even possibile?
ok i'm posting only a bit because it's kind of assignment so I have class Point.h
sorry for the mess but I'm trying a bit everything and it's not working for me.
#include "LinearTranslation.h"
class Point {
public:
int N;
double* coordinates;
public:
Point(int, double*);
virtual ~Point();
double operator[](int a);
//friend Point operator*(LinearTranslation l);
friend Point translation(LinearTranslation l);
};
LinearTranslation.h
#include "Point.h"
class LinearTranslation {
private:
int N;
double* vector;
double** matrix;
public:
//friend class Point;
LTrans(int,double*,double**);
LTrans(int);
virtual ~LTrans();
void write_vector();
void write_matrix();
LinearTranslation operator+(const LinearTranslation&);
friend Point& translation(LTrans l, Point p);
//friend Point& operator* (Point p, LTrans l);
};
in your class declaration:
//friend Point operator*(LinearTranslation l);
a friend operator overloading function takes two parameters for the function, you only declare one in your code. The most common example of a friend function is using the overloaded operator << like so:
friend ostream& operator<<(ostream& output, const Point& p);
note that this function takes the output as its first parameter, and the point as its second parameter.
Your fix would be to add in your operand to the function
friend Point operator*(LinearTranslation l, const int& MULT);

Problems with forward declaration - Friend functions and line / point classes

I have a demo program for understanding of friend function. I am stuck up with errors related to forward declaration stuff, I guess.
I have a point class which has x & y co-ordinates. The line class has two objects of point class. Now I have a function in line class which will calculate the slope of the line.
This is my program:
#include <iostream>
using namespace std;
class point
{
int x,y;
public:
point(int,int);
point();
friend float line::slope();
};
point::point(int a, int b)
{
x=a;
y=b;
}
point::point()
{
}
class line
{
point p1,p2;
public:
line(point,point);
float slope();
};
line::line(point p1, point p2)
{
this->p1=p1;
this->p2=p2;
}
float line::slope()
{
float s;
s=((float)p2.y-p1.y)/(p2.x-p1.x);
return s;
}
int main()
{
float sl;
point obj(5,10);
point obj1(4,8);
line obj3(obj,obj1);
sl=obj3.slope();
cout<<"\n slope:"<<sl;
return 0;
}
It is giving me compiler errors with respect to forward declarations due to the following:
When I try to define my line class first, it does not know about the point class. Even if I forward declare the point class, that wont suffice coz to create objects of the point class, the compiler should know the size of the point class and hence the whole class itself. Understood it through explanation in this answer: https://stackoverflow.com/a/5543788
If I define the point class first, it needs to know the friend function slope and hence the class line.
So I tried to provide the forward declaration for the line class and the slope function like this before defining the point class:
class line;
float line::slope();
class point
{
int x,y;
public:
point(int,int);
point();
friend float line::slope();
};
Now this gives me the following errors:
friend1.cpp:5: error: invalid use of incomplete type ‘struct line’
friend1.cpp:4: error: forward declaration of ‘struct line’
friend1.cpp:13: error: invalid use of incomplete type ‘struct line’
friend1.cpp:4: error: forward declaration of ‘struct line’
friend1.cpp: In member function ‘float line::slope()’:
friend1.cpp:9: error: ‘int point::y’ is private
friend1.cpp:43: error: within this context
friend1.cpp:9: error: ‘int point::y’ is private
friend1.cpp:43: error: within this context
friend1.cpp:9: error: ‘int point::x’ is private
friend1.cpp:43: error: within this context
friend1.cpp:9: error: ‘int point::x’ is private
friend1.cpp:43: error: within this context
.3. Next I tried to separate out the point class in point.h and point.cpp and line class in line.h and line.cpp. But still here there is a dependency on each other.
Though this should be possible theoretically, I cannot figure it out how to get it working.
Looking out for answers.
Thanks,
Raj
PS: This program is an effort to demonstrate the usage of friend functions alone. Where friend functions are of two types, this is an effort to deal with the second of this kind:
Friend functions which are independent.
Friend functions which are members of another class.
So, usage of friend classes are ruled out in this case.
Add line as a friend, not just a method:
friend class line;
Other remarks:
separate declarations from the implementations in header and implementation files.
prefer full qualification over using directives (i.e. remove using namespace std; and use std::cout instead.
prefer pass-by-reference for complex types - change line(point,point); to line(const point&, const point&);
EDIT For educational purposes - You can't declare that specific function as friend as the code is now because there's no full definition of the line class. Ergo, the following is the only approach:
class point;
class line
{
point *p1,*p2;
public:
line(point,point);
float slope();
};
class point
{
int x,y;
public:
point(int,int);
point();
friend float line::slope();
};
You forward-declare point and change the point members in line to point* (because point isn't a complete type yet). In point you now have the full definition of the line class, so you can declare the method as friend.
EDIT 2: For this particular scenario, it's not possible using point objects inside line because you'd need the full type. But line would also have to be fully defined in order to declare its member as friend.
Just make Line a friend of Point
class point
{
friend class line;
...
};
There's very little purpose in declaring individual methods as friends.
You can create a helper functor to calculate slope. This allows you to make the method of the functor a friend of the point without involving line.
class point;
class line;
struct slope {
float operator () (const point &, const point &) const;
float operator () (const line &) const;
};
class point {
int x,y;
public:
point(int a,int b) : x(a), y(b) {}
point() {}
friend float slope::operator ()(const point &, const point &) const;
};
class line {
point p1,p2;
public:
line(point a,point b) : p1(a), p2(b) {}
float slope() { return ::slope()(*this); }
friend float slope::operator ()(const line &) const;
};
With the implementations:
float slope::operator () (const point &p1, const point &p2) const {
float s;
s=((float)p2.y-p1.y)/(p2.x-p1.x);
return s;
}
float slope::operator () (const line &l) const {
return (*this)(l.p1, l.p2);
}
Under normal circumstances, I would avoid using friend here at all.
Prefer to add a function to point:
float slope_to(const point& other)
{// Not checked, just translated from your implementation
return ((float)other.y-y)/(other.x-x);
}
And implement:
float line::slope()
{
return p1.slope_to(p2);
}
This way line doesn't care about point's implementation and will not need to be changed when you implement 3D points.
Here is a demonstration of a friend of a free function (1.):
#include <iostream>
class point
{
int x, y;
public:
point(int, int);
friend std::ostream& operator <<(std::ostream& os, const point& p);
};
std::ostream& operator <<(std::ostream& os, const point& p)
{
return os << '(' << p.x << ", " << p.y << ')';
}
point::point(int a, int b)
:x(a)
,y(b)
{
}
int main()
{
point obj(5, 10);
std::cout << "\n point " << obj;
}
Here is an example building on your own code to have a friend of a member function (2.).
#include <iostream>
#include <memory>
using namespace std;
class point;
class line
{
std::auto_ptr<point> p1, p2;
public:
line(point&, point&);
float slope();
};
class point
{
int x, y;
public:
point(int, int);
friend float line::slope();
};
point::point(int a, int b)
:x(a)
,y(b)
{
}
line::line(point& p1, point& p2)
:p1(new point(p1))
,p2(new point(p2))
{
}
float line::slope()
{
return ((float)p2->y - p1->y) / (p2->x - p1->x);
}
int main()
{
point obj(5, 10);
point obj1(4, 8);
line obj3(obj, obj1);
cout << "\n slope:" << obj3.slope();
}
In order to reference point from within line, I use (auto_) pointers and references, since the class is declared at that point but not defined. line::slope() is declared in time for me to reference it as a friend of point. This circular dependency is a terrible code smell and should be avoided.
you refer to the line class in friend float line::slope(); before the class is defined.
just add the line class line; before the definition of the Point class
also change friend float line::slope(); to friend class line;