重写合格的虚拟方法
我和多个家长一起上 C++ 课;每个父级都定义了一个具有共同名称但目的不同的函数:
class BaseA
{
virtual void myFunc(); // does some task
};
class BaseB
{
virtual void myFunc(); // does some other task
};
class Derived : public BaseA, public BaseB;
如果是这样,我就没有问题了 - 我可以使用 using 语句来解决它的歧义,并且我可以选择要使用哪个函数使用基类名称和范围解析运算符进行调用。
不幸的是,派生类需要重写它们:
class Derived : public BaseA, public BaseB
{
virtual void BaseA::myFunc(); // Derived needs to change the way both tasks are done
virtual void BaseB::myFunc();
}
这不起作用,不是因为它引入了新的歧义(尽管可能),而是因为
“错误 C3240:'myFunc':必须是'BaseA'的非重载抽象成员函数”
“错误 C2838:成员声明中的非法限定名称”
在不同的情况下,我可能只是重命名这些方法,或者使它们成为纯虚拟的编译器建议。然而,类层次结构和许多外部问题使得第一个选项极其困难,而第二个选项则不可能。
有人有建议吗?为什么限定符只允许用于纯虚方法?有没有办法同时重写虚拟方法并解决歧义?
I have C++ class with multiple parents; each parent defines a function with a common name but a different purpose:
class BaseA
{
virtual void myFunc(); // does some task
};
class BaseB
{
virtual void myFunc(); // does some other task
};
class Derived : public BaseA, public BaseB;
If that was it, I would have no problem - I could resolve the ambiguity it with a using statement, and I could choose which one to call using the base class names and the scope resolution operator.
Unfortunately, the derived class needs to override them both:
class Derived : public BaseA, public BaseB
{
virtual void BaseA::myFunc(); // Derived needs to change the way both tasks are done
virtual void BaseB::myFunc();
}
This doesn't work, not because it introduces a new ambiguity (although it may), but because
"error C3240: 'myFunc' : must be a non-overloaded abstract member function of 'BaseA'"
"error C2838: illegal qualified name in member declaration"
Under different circumstances I might just rename the methods, or make them pure virtual as the compiler suggests. However, the class hierarchy structure and a number of external issues make the first option extremely difficult, and the second impossible.
Does anyone have a suggestion? Why are qualifiers only allowed for pure virtual methods? Is there any way to simultaneously override virtual methods and resolve ambiguities?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
Microsoft 允许该语法(从 Visual C++ 2005 开始可用)。 他们还为托管代码引入了一种新的、更强大的语法。
两者均未包含在 C++0x 中。
请参阅 http://www.open-std。 org/jtc1/sc22/wg21/docs/papers/2006/n2108.html
我认为这是一个解决方法:
Microsoft allows that syntax (it's available beginning in Visual C++ 2005). They also introduced a new, more powerful syntax for managed code only.
Neither one was included in C++0x.
See http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2006/n2108.html
I think this is a workaround:
您可以使用组合对象。
这并不是特别简洁,而且有些限制,但它确实在某些情况下有效。
You could use a composition object.
This isn't especially neat and it's somewhat restricted, but it does work some circumstances.
这是多重继承的大问题之一。当您继承多个同名函数来确定应该覆盖哪个函数时,总会出现问题,请参阅 钻石问题。您不能覆盖两者,因为函数语法(函数名称和运算符)必须是唯一的。
This is one of the big issues with multiple inheritance. There are always issues when you have multiple functions of the same name being inherited to determine which one is supposed to be overridden see The Diamond Problem. You cannot override both as the function syntax (function name and operators) must be unique.
我意识到这个问题很老了,但它有很多观点,如果您是界面的作者,有一个干净的方法可以解决这个问题。
许多人认为虚拟接口应该具有公共非虚拟函数,这些函数在内部遵循私有虚拟函数(我同意他们的观点)。这有一些优点,其中之一是非虚拟名称可以具有不同的含义,因为它们与接口的绑定更紧密:
这种方法的另一个优点是基类实现可以代表对象管理互斥体和哨兵之类的东西。派生函数,例如:
另一个优点是一些有用的自由函数运算符只需为整个类层次结构定义一次:
I realise that this question is old, but it's had a lot of views and there is a clean way to solve this if you are the author of the interfaces.
Many people believe that virtual interfaces should have public non-virtual functions that defer to private virtual functions internally (I agree with them). This has a few advantages, one of them being that non-virtual names can have distinct meanings since they are more strongly bound to the interface:
Another advantage of this approach is that base class implementations can manage things like mutexes and sentinels on behalf of the derived functions, for example:
Yet another advantage is that some useful free-function operators need only be defined once for the entire class hierarchy: