重载的std :: ostream运算符<<没有调用,stream获取变量地址而不是对象

时间:2012-03-23 14:27:27

标签: c++ operator-overloading iostream

当我在指针上调用operator<<时遇到问题。我搜索了SO并在Google上提出了我的问题,但所有提议的解决方案都没有解决我的问题。为了说明我的问题,请参阅我的代码的简化部分:

Marker.h

class Marker {
     ...
public:
     friend std::ostream& operator<<(std::ostream& out, const Marker& marker);
     friend std::ostream& operator<<(std::ostream& out, Marker* marker);
};

inline std::ostream& operator<<(std::ostream& out, const Marker& marker) {
      out << "Marker " << marker._name << " of type " << marker._type << " at position " << marker._position;
      return out;
}

 inline std::ostream& operator<<(std::ostream& out, Marker* marker) {
      out << *marker;
      return out;
 }

Landmark.h

 class Landmark {
       ...
       Marker* m_marker;
       ...
 };

Landmark.cpp

 void Landmark::print( std::ostream& out )
 {
     out << "Marker GENERIC: " << m_marker << std::endl;
     //out << "Marker GENERIC: " << *m_marker << std::endl;
 }

这不会在Visual Studio 2008下链接。我收到unresolved external symbol个错误。如果我删除了friend std::ostream& operator<<(std::ostream& out, Marker* marker);,代码会编译,但不是预期的格式化输出,而是只获得指向标记Marker* Landmark::m_marker的指针的内存地址。取消注释第二行会使我的代码无法编译。

我应该如何重载operator<<以便获得正确的输出?

我将不胜感激任何帮助!

3 个答案:

答案 0 :(得分:2)

这是一个简单的例子:

#include <iostream>

namespace mine {
class Marker {
public:
     friend std::ostream& operator<<(std::ostream& out, const Marker& marker);
     friend std::ostream& operator<<(std::ostream& out, Marker* marker);
};

inline std::ostream& operator<<(std::ostream& out, const Marker& marker) {
     out << "Marker";
     return out;
}

inline std::ostream& operator<<(std::ostream& out, Marker* marker) {
     out << *marker;
     return out;
}
} // namespace mine

int main() {
  mine::Marker marker;
  mine::Marker* m = &marker;

  std::cout << m << "\n";
}

它有效as expected

您指出的错误是链接器错误,它告诉您编译器发出了对未发出函数的方法的调用。

我认为你对我们说谎或者Visual Studio再次出错了。

  • 如果你撒谎(即没有复制确切的代码):请注意,在定义inline方法时,应该在使用之前包含整个方法体,因此 Landmark.cpp 应包括方法定义。
  • 或者,可能有必要通过在对它们进行关联之前预先声明该函数来帮助VS,以便VS了解它们确实存在于mine命名空间而不是全局命名空间中。

类似的东西:

namespace mine {
  class Marker;

  std::ostream& operator<<(std::ostream& out, const Marker& marker);
  std::ostream& operator<<(std::ostream& out, Marker* marker);

  class Marker {
  public:
    friend std::ostream& operator<<(std::ostream& out, const Marker& marker);
    friend std::ostream& operator<<(std::ostream& out, Marker* marker);
  };

  inline std::ostream& operator<<(std::ostream& out, const Marker& marker) {
    out << "Marker";
    return out;
  }

  inline std::ostream& operator<<(std::ostream& out, Marker* marker) {
    out << *marker;
    return out;
  }
} // namespace mine

答案 1 :(得分:1)

现在,您有重载来获取指针和对象的引用。您正在传递指针,因此不会使用引用的重载。

你想要反过来:摆脱占用指针的重载,并使用引用指针的重载。通过取消引用指针来使用它:out << *m_marker;

答案 2 :(得分:0)

更改此

friend std::ostream& operator<<(std::ostream& out, Marker* marker);

到此

friend std::ostream& operator<<(std::ostream& out, Marker marker);

然后使用此

out << "Marker GENERIC: " << *m_marker << std::endl;

当您传递实际对象时,输出操作符期望指针。