返回信息流具体问题简化如下。
A.h这个头文件定义了一个结构体A :
#ifndef A_H
#define A_H
struct A
{
int n;
char b;
};
//重载运算符==
bool operator==( const A &l, const A &r )
{
return l.n == r.n
&& l.b == r.b;
}
#endif
B.h这个头文件定义了一个类:
#ifndef B_H
#define B_H
#include "A.h"
class B
{
public:
A _a;
bool IsMatch(B* b);
};
#endif
B.cpp实现:
#include "B.h"
bool B::IsMatch(B* b)
{
return b->_a == this->_a;
}
main.cpp:
#include <iostream>
#include "B.h"
using namespace std;
int main()
{
cout<<"test"<<endl;
return 0;
}
编译没问题,就是link的时候报错:
error LNK2005: "bool __cdecl operator==(struct A const &,struct A const &)" (??8@YA_NABUA@@0@Z) already defined in B.obj
我实在是不知道怎么办了?
这是一条镜像帖。来源:北邮人论坛 / cpp / #79507同步于 2014/5/19
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖
[问题]相等运算符的重载
gdl
2014/5/19镜像同步10 回复
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
bool operator==( const A &l, const A &r ) 前加个inline。
或者只在h文件里声明 bool operator==( const A &l, const A &r ) ;实现放在cpp文件里。
把下面的代码放到struct A的定义里面去就好了。
//重载运算符==
bool operator==( const A &l, const A &r )
{
return l.n == r.n
&& l.b == r.b;
}
每个cpp文件都会产生一个.obj,所以你编译后,b.obj和main.obj里面都会有操作符重载函数的实现,重复定义,链接时候报错。
重新创建一个a.cpp,把这个重载函数的实现挪过去,也可以,不推荐,struct就是数据的封装,你重载的==也是对A的比较,放进去更符合逻辑。struct和class可以看成很类似的东西,默认成员权限为public。
头文件最好用来声明,定义放在源文件里面,内联函数都是class或者struct的成员函数。
这个……b.obj里面会有重载函数我好理解,但是main.obj怎么也会有呢,不明白
【 在 rollse 的大作中提到: 】
: 把下面的代码放到struct A的定义里面去就好了。
: 每个cpp文件都会产生一个.obj,所以你编译后,b.obj和main.obj里面都会有操作符重载函数的实现,重复定义,链接时候报错。
: 重新创建一个a.cpp,把这个重载函数的实现挪过去,也可以。
: ...................
main.cpp include了b.h, b.h include了a.h,include是会传递的
【 在 gdl 的大作中提到: 】
: 这个……b.obj里面会有重载函数我好理解,但是main.obj怎么也会有呢,不明白
如果把函数移到了a.cpp中,编译产生a.obj、b.obj和main.obj,只有a.obj有实现,b.obj和main.obj只有声明,这样理解有没有问题。
【 在 rollse 的大作中提到: 】
: main.cpp include了b.h, b.h include了a.h,include是会传递的
哇,inline这个好厉害。
我有个问题,是不是头文件中实现的函数,在编译的时候都会被写进包含他的cpp生成的obj中,所以造成obj中的重定义?
【 在 gaoweiwei 的大作中提到: 】
: bool operator==( const A &l, const A &r ) 前加个inline。
: 或者只在h文件里声明 bool operator==( const A &l, const A &r ) ;实现放在cpp文件里。
对的,但是还是建议把这个操作符重载函数放到struct里面去。这样你也不需要有个a.cpp了
【 在 gdl 的大作中提到: 】
: 如果把函数移到了a.cpp中,编译产生a.obj、b.obj和main.obj,只有a.obj有实现,b.obj和main.obj只有声明,这样理解有没有问题。
之前考虑过这样,但是我有点担心==这个运算符,要是写进去了能不能很好满足a==b,b==a,左右交换的特性。
【 在 rollse 的大作中提到: 】
: 对的,但是还是建议把这个操作符重载函数放到struct里面去。这样你也不需要有个a.cpp了
你考虑的有道理,加号和相等操作符必须满足交换律。
对于class和struct来说,如果把重载==的函数作为内联成员函数,只能接收一个同类型引用,也就是形参个数等于操作符所需操作数数量减一,实参和隐含的this指向的成员变量做比较。但是不满足交换律。因为函数实现中的两个对象,一个是指针,一个是引用。
把+和==的重载函数声明为友元函数,接收两个操作数就好了。
【 在 gdl 的大作中提到: 】
: 之前考虑过这样,但是我有点担心==这个运算符,要是写进去了能不能很好满足a==b,b==a,左右交换的特性。