【问题标题】:How to overload the operator<< from within a namespace如何在命名空间中重载 operator<<
【发布时间】:2016-08-15 00:51:08
【问题描述】:

这是我能想到的最小的包含示例。 首先是类的标题。每当使用

#pragma once
#ifndef EURO_H
#define EURO_H

#include <ostream>

namespace EU
{
   class Euro final
   {
   public:
        explicit Euro(double value);
        virtual ~Euro() = default;

        double getValue() const;

        friend std::ostream& operator<<(std::ostream &os, const Euro &euro);

    private:
        double m_value;
    };
}

#endif // EURO_H

现在是 .cpp

#include "euro.h"

using namespace EU;

Euro::Euro(double value)
{
    m_value = value;
}

double Euro::getValue() const
{
    return m_value;
}

std::ostream& operator<<(std::ostream &os, const Euro &euro)
{
    os << euro.getValue() << "EUR";
    return os;
}

最后是 main.cpp

#include "euro.h"

#include <iostream>

using namespace EU;

int main()
{
    auto e = Euro(3.14);
    std::cout << e << std::endl;
}

但是,当我使用以下代码编译时:

g++ -std=c++11 *.cpp

它吐出以下错误:

/tmp/ccP7OKC5.o: In function `main':
main.cpp:(.text+0x35): undefined reference to `EU::operator<<(std::ostream&, EU::Euro const&)'
collect2: error: ld returned 1 exit status

我做错了什么?

亲切的问候, 乔里斯

【问题讨论】:

  • 您可以通过完全没有value 来进一步简化它,而只是[尝试] 打印一个静态值!
  • 提示您不需要#pragma once 和标题保护#ifndef ... #define .... #endif

标签: c++ namespaces operator-overloading operator-keyword


【解决方案1】:

您希望using namespace EU; 将所有后续代码放入namespace EU,但它不会(否则您的int main 也会在命名空间中!)。这只是将已经在该命名空间中的东西带入范围。

这意味着您在命名空间内声明了朋友函数,但在全局范围内定义了一个 new 函数。对前者的调用将失败,因为它没有定义。

删除using namespace,并将namespace EU { } 包裹在euro.cpp 中的所有内容上。

【讨论】:

    【解决方案2】:

    从此更改您的 cpp 文件:

    #include "euro.h"
    
    using namespace EU;
    
    Euro::Euro(double value)
    {
        m_value = value;
    }
    
    double Euro::getValue() const
    {
        return m_value;
    }
    
    std::ostream& operator<<(std::ostream &os, const Euro &euro)
    {
        os << euro.getValue() << "EUR";
        return os;
    }
    

    到这里:

    #include "euro.h"
    
    namespace EU {  
    
    Euro::Euro(double value)
    {
        m_value = value;
    }
    
    double Euro::getValue() const
    {
        return m_value;
    }
    
    std::ostream& operator<<(std::ostream &os, const Euro &euro)
    {
        os << euro.getValue() << "EUR";
        return os;
    }
    
    } // namespace EU
    

    这将这个 cpp 文件中的代码定义为在命名空间内。您之前所做的是声明您的命名空间将在该文件的全局范围内使用,因为您没有将源代码定义为在命名空间内。

    【讨论】:

      猜你喜欢
      • 2011-10-17
      • 2018-08-09
      • 1970-01-01
      • 2015-02-17
      • 2011-01-29
      • 1970-01-01
      • 1970-01-01
      • 2012-04-26
      • 1970-01-01
      相关资源
      最近更新 更多