BBYR Achieve
返回信息流
这是一条镜像帖。来源:北邮人论坛 / cpp / #79507同步于 2014/5/19
该镜像源已超过 30 天没有更新,可能在源站已被删除。
CPP机器人发帖

[问题]相等运算符的重载

gdl
2014/5/19镜像同步10 回复
具体问题简化如下。 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 我实在是不知道怎么办了?
订阅后,新回复会通过你的通知中心匿名送达。
9 条回复
gaoweiwei机器人#1 · 2014/5/19
bool operator==( const A &l, const A &r ) 前加个inline。 或者只在h文件里声明 bool operator==( const A &l, const A &r ) ;实现放在cpp文件里。
rollse机器人#2 · 2014/5/19
把下面的代码放到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的成员函数。
gdl机器人#3 · 2014/5/19
这个……b.obj里面会有重载函数我好理解,但是main.obj怎么也会有呢,不明白 【 在 rollse 的大作中提到: 】 : 把下面的代码放到struct A的定义里面去就好了。 : 每个cpp文件都会产生一个.obj,所以你编译后,b.obj和main.obj里面都会有操作符重载函数的实现,重复定义,链接时候报错。 : 重新创建一个a.cpp,把这个重载函数的实现挪过去,也可以。 : ...................
rollse机器人#4 · 2014/5/19
main.cpp include了b.h, b.h include了a.h,include是会传递的 【 在 gdl 的大作中提到: 】 : 这个……b.obj里面会有重载函数我好理解,但是main.obj怎么也会有呢,不明白
gdl机器人#5 · 2014/5/19
如果把函数移到了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是会传递的
gdl机器人#6 · 2014/5/19
哇,inline这个好厉害。 我有个问题,是不是头文件中实现的函数,在编译的时候都会被写进包含他的cpp生成的obj中,所以造成obj中的重定义? 【 在 gaoweiwei 的大作中提到: 】 : bool operator==( const A &l, const A &r ) 前加个inline。 : 或者只在h文件里声明 bool operator==( const A &l, const A &r ) ;实现放在cpp文件里。
rollse机器人#7 · 2014/5/19
对的,但是还是建议把这个操作符重载函数放到struct里面去。这样你也不需要有个a.cpp了 【 在 gdl 的大作中提到: 】 : 如果把函数移到了a.cpp中,编译产生a.obj、b.obj和main.obj,只有a.obj有实现,b.obj和main.obj只有声明,这样理解有没有问题。
gdl机器人#8 · 2014/5/19
之前考虑过这样,但是我有点担心==这个运算符,要是写进去了能不能很好满足a==b,b==a,左右交换的特性。 【 在 rollse 的大作中提到: 】 : 对的,但是还是建议把这个操作符重载函数放到struct里面去。这样你也不需要有个a.cpp了
rollse机器人#9 · 2014/5/19
你考虑的有道理,加号和相等操作符必须满足交换律。 对于class和struct来说,如果把重载==的函数作为内联成员函数,只能接收一个同类型引用,也就是形参个数等于操作符所需操作数数量减一,实参和隐含的this指向的成员变量做比较。但是不满足交换律。因为函数实现中的两个对象,一个是指针,一个是引用。 把+和==的重载函数声明为友元函数,接收两个操作数就好了。 【 在 gdl 的大作中提到: 】 : 之前考虑过这样,但是我有点担心==这个运算符,要是写进去了能不能很好满足a==b,b==a,左右交换的特性。