最近复习了一下C++的一些基础知识,发现之前理解得不够深刻,或者当时只是简单过了一遍,复习的时候,有了一些新的收获。闲言少叙,书归正文:

问题:
C++的重载相等运算符operator==可以写成类成员函数,也可以写成全局普通函数,请问这对于同一个类型的两种重载相等运算符可以同时存在么?如何可以,那么它们的调用优先顺序是怎么样的?

我们还是用一个例子来说明:

#include <iostream>

class Person
{
private:
	int m_age;
public:
	Person(int nAge)
	{
		this->m_age = nAge;
	}

	int age() const
	{
		return m_age;
	}

	bool operator==(const Person& other)
	{
		std::cout << "call member function operator==" << std::endl;
		if (this->m_age == other.m_age)  //m_age不是私有成员变量么,为什么这样里可以直接写other.m_age?
		{
			return true;
		}
		return false;
	}
};

bool operator==(const Person& one, const Person& other)
{
	std::cout << "call normal function operator==" << std::endl;
	if (one.age() == other.age())
	{
		return true;
	}
	return false;
}

int main()
{
	Person p1(10);
	Person p2(10);

	if (p1 == p2)
	{
		std::cout << "p1 is equal with p2." << std::endl;
	}
	else
	{
		std::cout << "p1 is not equal with p2." << std::endl;
	}

	getchar();
	return 0;
}

运行结果:
在这里插入图片描述

如果注释掉
在这里插入图片描述
那么运行结果是什么?
在这里插入图片描述
C++重载相等运算符调用优先顺序:类成员函数 > 全局普通函数

如果某个类在逻辑上有相等性的含义,则该类应该定义operator==,这样做可以使得用户更容易使用标准库算法来处理这个类。

如果类定义了operator==,则这个类也应该定义一个operator!=,对于用户来说,当他们能使用==时,肯定也希望能使用!=,反之亦然。

现在又引出了另外一个问题:

在类成员函数

bool operator==(const Person& other)

if (this->m_age == other.m_age)  
//m_age不是私有成员变量么,为什么这样里可以直接写other.m_age?

实践证明,类(class)私有成员可以被类成员函数访问,不区分成员在哪个实例(instance)里。

也就是说,在类内部的成员函数中,哪怕是传入的对象,也是可以直接访问该对象的私有成员。(前提是该对象必须是本类型的一个对象)

这样类对象可以直接访问私有成员就合情合理了,而且这么做也确实是方便的。

在重载运算符时,类的对象可以直接访问私有成员解惑

如果大家想对其中的原因了解得更加详细的话,可以查看这篇博客:

C++类成员函数可以访问同类不同对象的私有成员

引用C++标准原文

A member of a class can be — private; that is, its name can be used
only by members and friends of the class in which it is declared. —
protected; that is, its name can be used only by members and friends
of the class in which it is declared, and by members and friends of
classes derived from this class (see 11.5). — public; that is, its
name can be used anywhere without access restriction.

访问限制标号是针对类而不是针对一个类的不同对象,只要同属一个类就可以不用区分同一个类的不同对象。因为 是类的成员函数,所以有权限访问私有数据成员。如果是在main函数中直接,那肯定就会报错了,不能访问,因为这是在类外不能访问私有数据成员。一个类的成员函数可以访问这个类的私有数据成员,我们要理解这个对类的访问限制,而不是针对对象。

C++的访问控制是类层面的 class-level, 而不是对象级别的object-level,

同一个类可以访问所有自己类实例的私有成员, 数据成员是类私有而不是实例私有, 成员是否可访问是类的性质, 而不是对象的性质。

重载operator== 还有第三种方式,就是成员的friend函数,类似全局的operator==方式,只是加了friend关键字,放在类中。

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐