Reputation: 47
I am attempting to create a class inside a namespace as it is a parameter for an assignment. however, I am running into some issues with calling function within the namespace, more specifically the operator functions. I have attached the code below.
Point.h
#ifndef HW_2_6_POINT_H
#define HW_2_6_POINT_H
#include <iostream>
using namespace std;
namespace udbhavAg
{
class Point
{
private:
double m_x; //private variables x & y
double m_y;
public:
Point(); //default constructor
Point(double inputX, double inputY); //Overloaded contructor.
Point(const Point &obj); //copy constructor
explicit Point(double value);
~Point(); //destructor
double X() const; //getter fucntions
double Y() const;
void X(const double& input); //setter functions
void Y(const double& input);
string toString() const; //to string fuucntion
double Distance() const; //distance to the origin
double Distance(Point p) const; //distance between two points
Point operator - () const; // Negate the coordinates.
Point operator * (double factor) const; // Scale the coordinates.
Point operator + (const Point& p) const; // Add coordinates.
bool operator == (const Point& p) const; // Equally compare operator.
Point& operator = (const Point& source); // Assignment operator.
Point& operator *= (double factor); // Scale the coordinates & assign.
};
}
#endif //HW_2_6_POINT_H
Points.cpp
//
// Created by Udbhav Agarwal on 18/05/20.
//
#include "Point.h"
#include <iostream>
#include <math.h>
using namespace std;
namespace udbhavAg
{
Point::Point() {} //defualt contructor
Point::Point(double inputX, double inputY) //paramter construcotr, overider
{
m_x = inputX;
m_y = inputY;
}
Point::Point(const Point &obj)//copy constructor
{
m_x = obj.m_x;
m_y = obj.m_y;
}
Point::~Point()
{
} // destructor
void Point::X(const double& input) // setting x
{
m_x = input;
}
void Point::Y(const double& input) // setting y
{
m_y=input;
}
double Point::X() const //returning x
{
return m_x;
}
double Point::Y() const //returing y
{
return m_y;
}
string Point::toString() const
{
//building the string for output.
string output = "Point(" + to_string(m_x) + "," + to_string(m_y) + ")";
return output ;
}
double Point::Distance(Point p) const //calculating the distance between 2 points
{
double distance = sqrt((pow(p.Y()-m_y,2))+(pow(p.X()-m_x,2)));
return distance;
}
double Point::Distance() const //calculating the distance from origin
{
double distance = sqrt((pow(m_x,2))+(pow(m_y,2)));
return distance;
}
Point Point::operator*(double factor) const
{
return Point(m_x*factor,m_y*factor);
}
Point & Point::operator*=(double factor)
{
m_x*=factor;
m_y*=factor;
return *this;
}
Point Point::operator+(const Point &p) const
{
return Point(m_x + p.m_x,m_y + p.m_y);
}
Point Point::operator-() const
{
return Point(-m_x,-m_y);
}
Point & Point::operator=(const Point &source)
{
if(this == &source)
{
return *this;
}
m_x = source.m_x;
m_y = source.m_y;
return *this;
}
bool Point::operator==(const Point &p) const
{
if(this ==&p)
{
return true;
}
if(this->m_y == p.m_y && this->m_x == p.m_x)
{
return true;
}
else
{
return false;
}
}
ostream &operator<<(ostream &os, const Point &p)
{
os <<"Point(" << p.X() <<"," << p.Y() << ")\n";
return os;
}
Point::Point(double value)
{
m_x = value;
m_y = value;
}
}
Main()
#include <iostream>
#include "Point.h"
using namespace std;
using namespace udbhavAg;
int main()
{
udbhavAg::Point p = udbhavAg::Point(1);
cout << p;
}
The compiler is throwing an error : error: invalid operands to binary expression ('std::__1::ostream' (aka 'basic_ostream') and 'udbhavAg::Point') cout << p;
Please help. I am unable to understand why I cannot access the << operator here. It works normally when I do not put the Point class in a namespace.
Upvotes: 1
Views: 1034
Reputation: 20141
There is nothing wrong with Creating Classes inside Namespace.
This is not what the exposed error is about:
error: invalid operands to binary expression ('std::__1::ostream' (aka 'basic_ostream') and 'udbhavAg::Point') cout << p;
The error indicates that the compiler struggles to resolve the stream operator in
udbhavAg::Point p = udbhavAg::Point(1);
cout << p;
At the first glance, this might be surprising because it is defined in Points.cpp
:
space udbhavAg
{
…
ostream &operator<<(ostream &os, const Point &p)
{
os <<"Point(" << p.X() <<"," << p.Y() << ")\n";
return os;
}
…
}
However, at the second glance, I realized that there is no prototype in Point.h
(or any other file which is #include
d in Main.cpp
).
So, the only file (aka. translation unit) where the stream operator can be used for class Point
is the file Points.cpp
.
To fix this, I would add the prototype to Point.h
:
std::ostream &operator<<(std::ostream &os, const Point &p);
Upvotes: 3