我正在编写一个具有三级继承的程序。我需要重载基类中的operator==
,然后在派生类中重写该函数(我不允许更改此设计)。
该函数是一个bool,它对两个对象进行成员比较。我如何处理超级回报值?在Java中获取此值很简单:我只是将overriden函数的第一行调用为super,例如:
retValue = super.myFunction();
我需要实现同样的结果,但是在C ++中并且运算符重载很糟糕。超载函数的一些伪代码将非常受欢迎。
我还有另外一个与此有关的问题;如果在不同子类的实例上使用运算符会发生什么?例如,sub1和sub2从base继承,将在Main中为以下代码行执行该函数的版本:
if (sub1 == sub2)
会产生编译错误吗?
编辑:首先,我是学生,所以我不能按照我想要的方式编写代码来完成这项任务。程序要求说明;
“车辆操作员过载:==运算符
Vehicle类需要覆盖==运算符。如果所有数据字段相等且其乘客列表相同,则两个对象相等。这需要在基类中定义,然后在派生类中重写。“
我真的没有任何代码可以发布,因为在阅读Billy的回复时我意识到我实际上已经编写了运行==函数的类(不允许我覆盖它,并且不会满足计划要求)。
示例;
if(sub1 == sub2)
完全是假设的。我实际上有一个Vehicle对象的数组,我有一个继承自Vehicle的Car和Airplane类,然后是一个继承自Car和继承自Airplane的Xwing的MagicSchoolBus。在Vehicle类中,我有一个int'vType_',它标识每个Vehicle实例所属的特定子类。为了防止运行时崩溃,我只需检查以确保对象在使用==运算符之前具有相同的vType_。
尽管我更喜欢编写比较函数,但我不允许这样做。我必须找到一种方法来使用基类中的operator ==函数的返回值,因为它正在比较几个数据成员,如果我在每个派生类中重写此代码,我当然会被降级。 / p>
如果我不能使用该返回值,我必须重写代码,否则当对象在基类的成员中具有不同的值但在派生类中具有相同的值时,我将得到错误的结果。
我将不得不将此函数重写为Vehicle类的成员,但我会发布它,希望它可能有用。 每个派生类都有一些特定于这些类型的车辆的成员,以及一组将要进行比较的Passenger对象。
//等于运算符重载以进行成员比较
bool operator ==(Vehicle& obj1,Vehicle& obj2) { bool retValue = false;
if (strcmp(obj1.getName(), obj2.getName()) == 0)
{
if (obj1.getType() == obj2.getType() && obj1.getFuel() == obj2.getFuel())
{
if (obj1.getRate() == obj2.getRate() && obj1.getStatus() == obj2.getStatus())
{
retValue = true;
}
}
}
return retValue;
}
答案 0 :(得分:3)
因为C ++与Java不同,支持多重继承,所以你需要明确指定SUPER::operator==()
需要使用哪个超级(用真正的超类名替换SUPER)。
答案 1 :(得分:2)
我需要在基类中重载==运算符,然后在派生类中重写该函数
这似乎是一件非常奇怪的事情。在可能的情况下,运算符重载通常应该是自由函数,而不是类成员。您可以发布一些代码来描述您想要更具体的内容吗?因为无法实现您想要的一般实现。例如。如果您通过基类指针比较Derived 1和Derived 2,编译器将如何知道调用哪个operator==
? Derived 1和Derived 2都实现了该功能,但没有办法选择。派生类应该只实现== 隐藏基类的实现,在少数情况下,某人可能需要做类似的事情。
不要将操作符重载与虚函数混合在一起 - 这很痛苦,而不是操作符重载的操作方式。
如何处理超级回报值?
你没有。在C ++中没有“超级”这样的东西(首先,如果从两个类继承,语言应该如何知道基本版本是什么?:P)。如果要调用基类的重载,则直接调用基类函数。例如:
class SomeBaseName
{
int aMember;
public:
bool operator==(const SomeBaseName& rhs)
{
return aMember == rhs.aMember;
};
};
class Derived : public SomeBaseName
{
int anotherMember;
public:
bool operator==(const Derived& rhs) //Note that this is not a virtual function, it is *hidden* instead.
{
if (!(SomeBaseName::operator==(rhs))
return false;
return anotherMember == rhs.anotherMember;
}
};
我真的建议你不要这样做..用操作符重载做事情是没有意义的。
如果在不同子类的实例上使用运算符会发生什么?例如,sub1和sub2从base继承,将为Main中的以下代码行执行该函数的哪个版本
两者都不会被召唤。调用不明确,会导致编译时错误。
最后,最后一条建议:不要试图用Java来学习C ++。学习C ++作为一门新语言。它们是不同的语言 - 比它们的类似语法所暗示的要多。 C ++允许你做几件事情,其中绝对没有Java中的等价物(例如指针算术,运算符重载,多重继承,模板元编程等),虽然有些东西是相似的在某些地方,两种语言的惯用例都彼此截然不同。如果你认为某些东西是Java等价物,当语言不同或C ++将概念堆积到它(非常不同的)对象模型上时,你会感到困惑。
答案 2 :(得分:1)
如果从类继承,则必须使用显式限定符。没有关键字。
class A {
public:
virtual bool operator==(const A&);
};
class B : public A {
public:
virtual bool operator==(const B& other) {
bool result = A::operator==(other);
//.. do other stuff
}
};
如果你没有定义一个新的,那么就会调用一个。