c – 未定义的对运算符<<的引用
我有一个普通课(不是一个模板,就是这样),一个私人的朋友运算符<< 它的声明是:
std::ostream& operator<<(std::ostream& out,const Position& position); 在cpp文件中,它的定义是: std::ostream& operator<<(std::ostream& out,const Position& position) { out << position.getXPoint() << "," << position.getYPoint(); return out; } 它正在被编译,然后链接到使用它的主要功能,但是当我使用它,我得到一个未定义的引用… 然而,当我将定义添加到主cpp文件的顶部并删除朋友声明时,它工作正常… 我在我的主要功能中使用它 std::cout << node->getPosition() << std::endl; 不多不少… 遇到链接器错误
并且继承类头 #ifndef PATHFINDER_H #define PATHFINDER_H #include <ostream> #include <istream> #include <list> #include <vector> #include <stdexcept> #include <cstring> namespace pathfinder { class Node; typedef unsigned int GCost; typedef std::vector<std::vector<Node*> > World; typedef std::vector<Node*> WorldRow; class Position { public: typedef unsigned int point_type; private: point_type* xPoint_; point_type* yPoint_; friend std::ostream& operator<<(std::ostream& out,const Position& position); public: Position(const point_type& xPoint = 0,const point_type& yPoint = 0); Position(const Position& position); Position(Position&& position); ~Position(); Position& operator=(const Position& position); Position& operator=(Position&& position); point_type getXPoint() const; point_type getYPoint() const; void setXPoint(const point_type& xPoint); void setYPoint(const point_type& yPoint); }; class Node { private: bool* isPassable_; bool* isStartingNode_; bool* isTargetNode_; Position* position_; GCost* additionalGCost_; Node* parent_; public: Node(const bool& isPassable = true,const bool& isStartingNode = false,const bool& isTargetNode = false,const Position& position = Position(0,0),const GCost& additionalGCost = 0,Node* parent = nullptr); Node(const Node& node); Node(Node&& node); ~Node(); Node& operator=(const Node& node); Node& operator=(Node&& node); bool isPassable() const; bool isStartingNode() const; bool isTargetNode() const; Position getPosition() const; GCost getAdditionalGCost() const; Node* getParent() const; void setAsPassable(const bool& isPassable); void setAsStartingNode(const bool& isStartingNode); void setAsTargetNode(const bool& isTargetNode); void setPosition(const Position& position); void setAdditionalGCost(const GCost& additionalGCost); void setParent(Node* parent); }; class WorldHelper { public: static World fromStream(std::istream& input); static void syncPositions(World& world); static void uninitializeWorld(World& world); static Node* findStartingNode(const World& world); static Node* findTargetNode(const World& world); }; class Pathfinder { public: virtual std::list<Node*> operator()(World& world) const = 0; }; }; #endif //PATHFINDER_H 现在删除好友声明后,我收到错误信息,如:
它发生在与std :: cout语句相同的行上… 那么什么交易… 提前致谢 解决方法
我的猜想是,从描述中你宣告两个操作符<但只定义一个.例如:
namespace A { struct B { friend std::ostream& operator<<( std::ostream&,B const & ); // [1] }; } std::ostream& operator<<( std::ostream& o,A::B const & ) { // [2] return o; } 行[1]声明一个A ::运算符<<函数可以通过类型B上的ADL找到,但是[2]声明并定义了:: operator<<<.当编译器看到代码时: A::B b; std::cout << b; 它使用ADL并找到A :: operator<< (来自朋友声明)并使用它,但该功能未定义.如果你删除了这个朋友的声明,那么就有一个运算符<<在全局命名空间中声明和定义,并通过定期查找找到它. 还要注意,如果在程序中使用指令,这可能更难发现,因为[2]中的定义可能不会为参数显式命名A命名空间.这也可以解释你可以定义类型的其余成员: // cpp [assume that the definition of B contained a member f using namespace A; void B::f() { } B :: f的定义驻留在全局命名空间中(代码中),但是由于using指令,B将在A命名空间中找到,并且类型说明符将等价于A :: B,使定义等同于void :: A :: B :: f(){}解析B.这不会发生免费函数. 我建议您避免使用指令,因为它们允许这样的微妙错误.另外请注意,您可以明确地定义命名空间中的运算符(但是您还需要在命名空间中声明它: namespace A { struct B { friend std::ostream& operator<<( std::ostream&,B const & ); }; std::ostream& operator<<( std::ostream&,B const & ); } std::ostream& A::operator<<( std::ostream& o,B const & ) { return o; } 这个技巧(通过完全限定)在自然命名空间之外定义自由函数)有时用于避免定义隐式声明它的函数,这很容易出现这种类型的错误.例如,如果您在正确的命名空间中定义了运算符,但签名略有不同: namespace A { struct B { friend std::ostream& operator<<( std::ostream&,B const & ); // [1] }; std::ostream& operator<<( std::ostream&,B & ) { // [3] return o; } } [3]中的定义也是一个声明,但它声明一个与[1]中声明的函数不同的函数,您可能会最终抓住头,问为什么链接器没有找到[1]. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |