C++运算符重载需要注意的地方

Posted 牧秦丶

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C++运算符重载需要注意的地方相关的知识,希望对你有一定的参考价值。

有时候自己写一个类,需要重载运算符,但对于一些操作符(如==<>等),可以在类里写,也可以在类外写。那么 C++ 编译器会去怎么调用呢?


首先,我们知道,“重载” 机制可以允许多个函数有相同的函数名,但参数列表必须不同。C++编译器经过名字改编(name mangling),可以在调用时依据所传实参找到“最符合”的函数实体进行调用。而运算符重载亦是如此。


首先,我们有一个类:

class CMyCls

public:
	bool operator == (const CMyCls& rhs);				// 1.
	
	bool operator == (const CMyCls& rhs) const;			// 2.

	bool operator == (CMyCls& rhs);						// 3.

	bool operator == (CMyCls& rhs) const;				// 4.
;


void f1 (CMyCls& lhs, const CMyCls& rhs);

	lhs == rhs;


void f2 (const CMyCls& lhs, const CMyCls& rhs);

	lhs == rhs;


void f3 (CMyCls& lhs, CMyCls& rhs);

	lhs == rhs;


void f4 (const CMyCls& lhs, CMyCls& rhs)

	lhs == rhs;

那么 f1 - f4 这四个函数将会如何调用呢?其实,f1函数会调到CMyCls类中1 处注释所标的函数,f2会调到 2 处注释所标的函数,f3f4依次类推。


那么,如果我在类里面有一个运算符重载,在类外也有,会调用哪一个呢?比如:

class CMyCls

public:
	bool operator == (const CMyCls& rhs) const
	
		// ...
	
;


bool operator == (const CMyCls& lhs, const CMyCls& rhs)

	// ...



void f(const CMyCls& lhs, const CMyCls& rhs)

	lhs == rhs;

但很不幸的是,这样编不过。因为对于 f 函数的调用来说,编译器不知道调哪一个会比较好,因为同时存在两份“最适合”的重载函数,所以产生歧义。但这样是可以编过的,思考下为什么:

class CMyCls

public:
	bool operator == (const CMyCls& rhs)
	
		// ...
	
;


bool operator == (const CMyCls& lhs, const CMyCls& rhs)

	// ...



void f1(const CMyCls& lhs, const CMyCls& rhs)

	lhs == rhs;



void f2(CMyCls& lhs, const CMyCls& rhs)

	lhs == rhs;

上面 f1会调到全局的函数operator ==,而f2会调到 CMyCls的成员函数operator ==。所以,最好的写法是只在类里或类外重载两个参数均为const的版本。




以上是关于C++运算符重载需要注意的地方的主要内容,如果未能解决你的问题,请参考以下文章

C++重载运算符小结与注意点

C++提高:运算符重载

C++提高:运算符重载

对重载可变参数模板函数的歧义调用

C++ 运算符重载三(链式编程)

C++:-> 运算符重载:以不同方式处理 const / nonconst 访问