假设我有一个对象Node
,它有一个函数addPath()
,期望另一个Node
作为参数。
virtual void Node::addPath(Node * otherNode)
{
// does something with otherNode
}
现在,我说我来自Node
。让我们调用此DerivedNode
,它有一个新函数foo()
。我想覆盖addPath
方法。我也知道当我拨打DerivedNode::addPath
时,参数将始终是另一个DerivedNode
。这意味着我希望能够在foo()
方法中调用addPath()
。
int DerivedNode::foo();
void DerivedNode::addPath(Node * otherNode)
{
int x = foo(); // no problem
int y = otherNode->foo() // BAD! otherNode is typed as Node, not DerivedNode
}
我无法致电otherNode->foo()
。我该怎么办?
显然我知道我可以投,但这似乎是一个笨重的新手解决方案。我们有更优雅的东西吗?我觉得这应该是一个相当常见的用例。
答案 0 :(得分:1)
virtual int foo() = 0;
答案 1 :(得分:0)
您不能调用'foo'方法,因为它不是基本节点的成员。实际上,您可以进行转换,但要确保节点参数的类型确实是DerivedNode,否则您将获得异常。 是的,您可以从addPath方法调用x = foo()方法,因为您正在从DerivedNode类进行调用。
或者您可以将foo()定义为基类中的虚方法。要么使它抽象,但在这种情况下,您将无法创建Node实例,或者您可以提供默认/空实现。
答案 2 :(得分:0)
假设您的Node类是2种节点的抽象类:
在这种情况下,出现了两个问题:
一旦你回答了这些问题,你就可以更清楚地了解这些方法所承担的责任 - 而这反过来会给你一个提示 (在哪个班级中)给它们。
答案 3 :(得分:-1)
如果只有一个派生类需要foo()操作,那么你应该使用动态强制转换(或重新考虑你的设计)。
如果" foo" operation是一个适用于多个派生类的操作,那么你应该在你的基类(Node)中添加一个虚方法foo()。
如果(几乎)每个派生类都需要某种类型的foo操作,那么使foo()方法成为抽象(纯粹的。)
如果许多派生类不需要foo()操作,那么将其作为" no-operation"在基类中,所以不需要foo()的派生类可以简单地忽略该问题。
以下代码使用此技术。
class Node
{
virtual void Node::addPath(Node * otherNode)
{
// does something with otherNode
}
virtual void foo()
{
// nothing to do in the base class
}
};
class DerivedNode : public Node
{
void DerivedNode::addPath(Node * otherNode)
{
int x = foo(); // no problem
int y = otherNode->foo(); // Now this works.
}
void foo()
{
// this is the DervivedNode-specific foo!
Node::foo(); // just in case the base class has an opinion
do my foo-ish stuff here;
}
};