我有一个实现==运算符的基类.我想编写另一个类,继承基类,并且应该重新实现==运算符.
以下是一些示例代码:
#include <iostream>
#include <string>
class Person
{
public:
Person(std::string Name) { m_Name = Name; };
bool operator==(const Person& rPerson)
{
return m_Name == rPerson.m_Name;
}
private:
std::string m_Name;
};
class Employee : public Person
{
public:
Employee(std::string Name, int Id) : Person(Name) { m_Id = Id; };
bool operator==(const Employee& rEmployee)
{
return (Person::operator==(rEmployee)) && (m_Id == rEmployee.m_Id);
}
private:
int m_Id;
};
void main()
{
Employee* pEmployee1 = new Employee("Foo" , 1);
Employee* pEmployee2 = new Employee("Foo" , 2);
if (*pEmployee1 == *pEmployee2)
{
std::cout << "same employee\n";
}
else
{
std::cout << "different employee\n";
}
Person* pPerson1 = pEmployee1;
Person* pPerson2 = pEmployee2;
if (*pPerson1 == *pPerson2)
{
std::cout << "same person\n";
}
else
{
std::cout << "different person\n";
}
}
Run Code Online (Sandbox Code Playgroud)
此示例代码给出以下结果:
different employee
same person
Run Code Online (Sandbox Code Playgroud)
在我想要的地方,即使处理Person*指针,也要确保它们不同.
我该怎么解决这个问题?
谢谢 !
Joh*_*McG 10
你想要做的是基本上"虚拟化"比较运算符.
由于运营商不能是虚拟的,因此您需要将其委托给其他人.这是一种可能的解决方案.
class Person
{
public:
/* ... */
bool operator==(const Person& rhs)
{
return m_Name == rPerson.m_Name && this->doCompare(rhs);
}
private:
virtual bool doCompare() = 0;
};
}
class Employee : public Person
{
/* ... */
private:
virtual bool doCompare(const Person& rhs)
{
bool bRetval = false;
const Employee* pRHSEmployee = dynamic_cast<const Employee*>(&rhs);
if (pEmployee)
{
bRetval = m_Id == pRHSEmployee->m_Id
}
return bRetval;
}
};
Run Code Online (Sandbox Code Playgroud)
这个问题没有说清楚人是否需要成为一个具体的阶级.如果是这样,你可以使它不是纯虚拟的,并实现它返回true.
这也使用RTTI,您可能会或可能不会满意.
这个问题没有简洁的解决方案.
在C++中,实际上这不是问题.在平等的基础上比较实体有什么意义?
编辑:关于适用于实体的平等相关性的一些冥想链接:
EDIT2(2018年11月27日):
这里还有另一个问题,问题在OO设计中也有其根源,而不是在C++中.设计一个reflexive(x == x),symmetric(x == y <=> y == x)和transitive(x == y && y == z => x == z)的比较运算符是不可能的,它也符合Liskov Substitution Principle.在Joshua Bloch的Effective Java,第2版中,有一个彻底的证明.
TL; DR:假设我们ColouredPoint继承了Point一个函数,该函数用于对Points的引用,并且需要对它们进行比较.如果{1,2} == {1,2,blue},我们最终会得到{1,2,blue} == {1,2,green}.或者我们拒绝比较有色点的点,这会破坏LSP.等等.没有解决方案.我的结论是继承比较,虽然它很有吸引力,但它不起作用.
如果你有一个人和一个雇员,你仍然会遇到一个重大问题 - 这个人可能与雇员相等,但雇员与雇员不同.即:
(employee == person) != (person == employee)
Run Code Online (Sandbox Code Playgroud)
这是一件坏事(tm).基本上你已经创建了一个非对称的相等运算符
编辑:
好的,没有虚拟运算符 - 添加我认为在其他地方建议的虚拟比较函数 - 但是你仍然存在对称问题.