Udbhav Agarwal
Udbhav Agarwal

Reputation: 47

Creating Classes inside Namespace C++

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

Answers (1)

Scheff&#39;s Cat
Scheff&#39;s Cat

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 #included 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

Related Questions