11 c++ operator-overloading operators
我有一个常规类(不是模板,也就是说)与私人朋友运营商<<
它的声明是:
std::ostream& operator<<(std::ostream& out, const Position& position);
Run Code Online (Sandbox Code Playgroud)
在cpp文件中,它的定义是:
std::ostream& operator<<(std::ostream& out, const Position& position)
{
out << position.getXPoint() << "," << position.getYPoint();
return out;
}
Run Code Online (Sandbox Code Playgroud)
它正在编译然后链接到使用它的main函数,但是当我使用它时,我得到一个未定义的引用...
但是,当我将定义添加到主cpp文件的顶部并删除友元声明时,它工作正常...
继承人我在主要功能中如何使用它
std::cout << node->getPosition() << std::endl;
Run Code Online (Sandbox Code Playgroud)
不多也不少......
继承人错误
/home/luke/Desktop/pathfinder/parse_world.cpp:34:对`pathfinder :: operator <<(std :: ostream&,pathfinder :: Position const&)'的未定义引用
并且继承了班级头...
#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
Run Code Online (Sandbox Code Playgroud)
现在删除好友声明后,我收到如下错误消息:
无法将'std :: ostream {aka std :: basic_ostream}'左值绑定到'std :: basic_ostream &&'
它出现在与std :: cout语句相同的行上...
那么,这笔交易是什么......
提前致谢
Dav*_*eas 16
我的猜测,从描述中你是宣告两个operator<<但只定义一个.例如:
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;
}
Run Code Online (Sandbox Code Playgroud)
第[1]行声明了一个A::operator<<可以在类型上通过ADL找到的函数B,但是[2]声明并定义了::operator<<.当编译器看到代码时:
A::B b;
std::cout << b;
Run Code Online (Sandbox Code Playgroud)
它使用ADL并查找A::operator<<(来自友元声明)并使用它,但该函数未定义.如果删除friend声明,则operator<<在全局命名空间中有一个声明和定义的实例,并且可以通过常规查找找到.
另请注意,如果在程序中使用指令,则可能更难以发现,因为[2]中的定义可能未明确A命名参数的命名空间.这也可以解释您可以定义该类型的其余成员:
// cpp [assume that the definition of B contained a member f
using namespace A;
void B::f() {
}
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
这个技巧(通过完全限定来定义其自然命名空间之外的自由函数)有时用于避免隐式声明它的函数的定义,这容易出现这种类型的错误.例如,如果您在适当的命名空间中定义了运算符,但签名略有不同:
namespace A {
struct B {
friend std::ostream& operator<<( std::ostream&, B const & ); // [1]
};
std::ostream& operator<<( std::ostream&, B & ) { // [3]
return o;
}
}
Run Code Online (Sandbox Code Playgroud)
[3]中的定义也是一个声明,但是它声明了一个与[1]中声明的函数不同的函数,并且你最终可能会不知道为什么链接器没有找到[1].
| 归档时间: |
|
| 查看次数: |
22407 次 |
| 最近记录: |