【问题标题】:Creating Classes inside Namespace C++在命名空间 C++ 中创建类
【发布时间】:2020-05-18 05:28:37
【问题描述】:

我正在尝试在命名空间内创建一个类,因为它是分配的参数。但是,我在命名空间中调用函数时遇到了一些问题,更具体地说是运算符函数。我附上了下面的代码。

点.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

点数.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;
        }



}

主要()

#include <iostream>
#include "Point.h"
using namespace std;
using namespace udbhavAg;
int main()
{
    udbhavAg::Point p = udbhavAg::Point(1);
    cout << p;
}

编译器抛出错误:错误:二进制表达式的操作数无效('std::__1::ostream'(又名'basic_ostream')和'udbhavAg::Point') cout

请帮忙。我无法理解为什么我无法在此处访问

【问题讨论】:

  • 您没有接受 const int 的 Point 构造函数。您有接受两个双精度数和一个点类型但不接受整数的构造函数,请尝试在 1 之后添加 .0。
  • @SPlatten 暴露的错误与构造函数无关。这是关于流运算符operator&lt;&lt;()
  • 有一个std::ostream&amp; operator&lt;&lt;(std::ostream&amp;, const Point&amp;) 的定义,但它“隐藏”在Points.cpp 中。在Point.h 中添加它的声明以解决您的问题。
  • 我们经常看到这种情况,新手学习新东西(在这种情况下是命名空间),所以任何问题都会归咎于命名空间。事实上它只是一个缺少的声明,不管有没有命名空间都会导致错误。
  • @Scheff 哦,是的,这完全可以理解,尤其是当您对正在学习的所有新内容感到有点不知所措时。但是作为程序员,你必须学习的一件事就是不要对你的代码做太多假设。

标签: c++


【解决方案1】:

在命名空间中创建类没有任何问题。

这不是暴露的错误:

error: invalid operands to binary expression ('std::__1::ostream' (aka 'basic_ostream') and 'udbhavAg::Point') cout &lt;&lt; p;

该错误表明编译器难以解析中的流运算符

    udbhavAg::Point p = udbhavAg::Point(1);
    cout << p;

乍一看,这可能会令人惊讶,因为它是在Points.cpp中定义的:

space udbhavAg
{

        ostream &operator<<(ostream &os, const Point &p)
        {
            os <<"Point(" << p.X() <<"," << p.Y() << ")\n";
            return os;
        }

}

然而,再看一眼,我意识到Point.h(或Main.cpp 中的#included 的任何其他文件)中没有原型。

因此,流运算符可用于class Point 的唯一文件(又名翻译单元)是文件Points.cpp

为了解决这个问题,我会将原型添加到Point.h

       std::ostream &operator<<(std::ostream &os, const Point &p);

【讨论】:

  • 但是为什么没有命名空间它可以工作?从技术上讲,
  • ostream &operator
  • @UdbhavAgarwal 无论您是否将其与您自己的命名空间一起使用,是否没有声明(包含在您打算使用 operator&lt;&lt; 的每个文件中),除此之外的任何其他文件中都不知道该运算符它被定义的那个。如果你使用using namespace std;,你当然可以声明它ostream &amp;operator&lt;&lt;(ostream&amp; os, const Point&amp; p);(不用在每个ostream前加上std::)。 (请参阅我的其他评论,为什么using namespace std; 不好。)但是,这不是我回答的重点。关键是你完全忘记了声明。 ;-)
猜你喜欢
  • 1970-01-01
  • 2012-10-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-09-27
  • 2011-08-04
相关资源
最近更新 更多