从基类调用派生类函数
class base
{
public:
virtual void start();
virtual void stop();
void doSomething() { start(); .... stop(); }
}
class derived : public base
{
public:
void start();
void stop();
}
但是,当我在派生类中调用 doSomething()
时,它使用的是它自己的 Start()
和 Stop()
定义 - 而不是派生类那些。
我不想在派生类中重写 doSomething() ,因为它与基类相同。我做错了什么?
抱歉,如果不清楚。
派生类中 Start() 和 Stop() 的行为是不同的(它是不同的机器) - 但我想使用原始基类 doSomething() 因为它没有改变。它只需使用新的派生类代码启动()和停止()。
class base
{
public:
virtual void start();
virtual void stop();
void doSomething() { start(); .... stop(); }
}
class derived : public base
{
public:
void start();
void stop();
}
But when I call doSomething()
in the derived class it is using it's own definition of Start()
and Stop()
- not the derived ones.
I don't want to rewrite doSomething()
in the derived class because it would be identical to the base one. What am I doing wrong?
Sorry if that wasn't clear.
The behaviour of Start() and Stop() in the derived class is different (it's a different machine) - but I want to use the original base class doSomething() because that hasn't changed. It just has to start() and stop() using the new derived class code.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
您发布的代码应该按照您想要的方式工作。在
衍生
实例上调用doSomething
将调用衍生< 中定义的重写
start
和stop
函数/代码>。不过,有一个例外。如果您在
base
的构造函数或析构函数中调用doSomething
(无论是直接还是间接),则start
和stop< 的版本被调用的 /code> 将是在
base
中定义的。这是因为在这种情况下,您实际上还没有有效的派生
实例。它要么没有完全构造,要么部分被破坏,因此该语言会阻止您调用使用部分对象的方法。如果您不是从
base
构造函数或析构函数调用它,那么问题就比这里显示的更多了。The code you've posted should work the way you want. Calling
doSomething
on an instance ofderived
will call the overriddenstart
andstop
functions defined inderived
.There's an exception to that, though. If you call
doSomething
in the constructor or destructor ofbase
(whether directly or indirectly), then the versions ofstart
andstop
that get called will be the ones defined inbase
. That's because in those circumstances, you don't actually have a validderived
instance yet. It's either not fully constructed or partially destructed, so the language prevents you from calling methods that would use the partial object.If you're not calling it from a
base
constructor or destructor, then there is more to the problem than what's shown here.更新
根据您下面的评论,您试图使 doSomething() 调用派生类的 start() 和 stop() 版本,我对您问题的更新答案如下:
您定义 Base 和 的方式没有任何问题衍生的。您可能正在经历所谓的“代码切片”,即您在声明类型为“Base”的对象上调用“doSomething()”,而不是“Base*”或“Base&”,这将导致对象正在转换为 Base 类型。
坏例子:
好例子:
旁注:您应该使用scoped_ptr、shared_ptr、unique_ptr 或其他一些智能指针类,而不是像我的示例中那样直接使用指针;但是,为了不掩盖问题,我选择在本示例中使用原始指针。有关“切片”的更多信息,请参阅:
原始解决方案
你可以这样做:
如果你这样做,那么 doSomething() 将使用未被覆盖的 start/stop 的内部版本。当构造函数/析构函数需要与虚拟方法共享逻辑时,您会经常发现这种模式。
另外,与当前的问题无关,不要忘记,每当您创建具有虚拟方法的类时,您都应该创建一个虚拟析构函数。
Update
Based on your comment below that you are trying to make doSomething() call the Derived class's version of start() and stop(), my updated answer to your question is as follows:
There is nothing wrong with the way that you defined Base and Derived. You are probably experiencing what is called "code slicing", where you are calling "doSomething()" on an object whose declared type is "Base", instead of "Base*" or "Base&", which will result in the object being converted to type Base.
Bad example:
Good example:
Side-note: you should use a scoped_ptr, shared_ptr, unique_ptr, or some other smart pointer class instead of using a pointer directly as in my example; however, to not obscure the issue, I have opted to use a raw pointer in this example. For more information about "slicing", see:
Original solution
You could do something like this:
If you do this, then doSomething() will use the internal version of start/stop which isn't overridden. You will find this pattern a lot, when a constructor/destructor needs to share logic with a virtual method.
Also, not related to the issue at hand, don't forget that you should always create a virtual destructor whenever you create a class that has virtual methods.