在 C++ 中覆盖运算符以使用派生的 class
Overriding an operator to use the derived class in C++
我试图覆盖子 class 中的虚拟比较运算符,但我收到一个编译器错误,指出派生的 class 没有实现基础 class' 虚拟运算符。
我感觉这与我的派生运算符不使用基本 class' 参数类型有关。
简化版如下:
struct Base {
virtual bool operator ==(const Base) const;
};
struct Derived : Base {
bool operator ==(const Derived) const {
// implementation goes here
}
};
我有办法做到这一点,还是我必须在 Derived
实现中进行类型检查以查看它是否是正确的类型?
I have a feeling it's to do with the fact that my derived operator
doesn't use the base class' argument type.
确实如此。基础 class 必须采用 const reference(以便它可以具有动态类型 Derived
,然后您将覆盖声明为:
bool operator ==(const Base& rhs) const {
const auto pRhs = dynamic_cast<const Derived*>(&rhs);
if (pRhs == nullptr)
{
return false; // Not a derived. Cannot be equal.
}
// Derived/Derived implementation goes here
}
注意:像这样的虚拟比较运算符很容易出错。你需要一个很好的激励例子来做到这一点。特别是,如果你写:
Derived d;
Base b;
if (d == b) // All is well - derived override called, and returns false.
if (b == d) // Uh-oh! This will call the *base* version. Is that what you want?
还有:
Derived d;
DerivedDerived dd;
if (d == dd) // Did you want to use the DerivedDerived comparison?
您必须在 Derived 实现中键入检查参数是否具有预期类型。
对于运算符,您可能更愿意定义一个虚拟标准方法,然后通过调用该方法来实现您的运算符。这样可以避免操作员出现意外或过大的签名。
struct Base {
virtual int compare(const Base& source) const { return 0; }
bool operator ==(const Base& source) const
{ return compare(source) == 0; }
};
struct Derived : Base {
int compare(const Base& asource) const override
{ const Derived* source = dynamic_cast<const Derived*>(&asource);
int result = -2;
if (source) { ... result = ...; }
return result;
}
// redefinition to force the expected/right signature at this level
bool operator==(const Derived& source) const
{ return compare(source) == 0; }
};
我试图覆盖子 class 中的虚拟比较运算符,但我收到一个编译器错误,指出派生的 class 没有实现基础 class' 虚拟运算符。
我感觉这与我的派生运算符不使用基本 class' 参数类型有关。
简化版如下:
struct Base {
virtual bool operator ==(const Base) const;
};
struct Derived : Base {
bool operator ==(const Derived) const {
// implementation goes here
}
};
我有办法做到这一点,还是我必须在 Derived
实现中进行类型检查以查看它是否是正确的类型?
I have a feeling it's to do with the fact that my derived operator doesn't use the base class' argument type.
确实如此。基础 class 必须采用 const reference(以便它可以具有动态类型 Derived
,然后您将覆盖声明为:
bool operator ==(const Base& rhs) const {
const auto pRhs = dynamic_cast<const Derived*>(&rhs);
if (pRhs == nullptr)
{
return false; // Not a derived. Cannot be equal.
}
// Derived/Derived implementation goes here
}
注意:像这样的虚拟比较运算符很容易出错。你需要一个很好的激励例子来做到这一点。特别是,如果你写:
Derived d;
Base b;
if (d == b) // All is well - derived override called, and returns false.
if (b == d) // Uh-oh! This will call the *base* version. Is that what you want?
还有:
Derived d;
DerivedDerived dd;
if (d == dd) // Did you want to use the DerivedDerived comparison?
您必须在 Derived 实现中键入检查参数是否具有预期类型。
对于运算符,您可能更愿意定义一个虚拟标准方法,然后通过调用该方法来实现您的运算符。这样可以避免操作员出现意外或过大的签名。
struct Base {
virtual int compare(const Base& source) const { return 0; }
bool operator ==(const Base& source) const
{ return compare(source) == 0; }
};
struct Derived : Base {
int compare(const Base& asource) const override
{ const Derived* source = dynamic_cast<const Derived*>(&asource);
int result = -2;
if (source) { ... result = ...; }
return result;
}
// redefinition to force the expected/right signature at this level
bool operator==(const Derived& source) const
{ return compare(source) == 0; }
};