[英]Calling derived class function from base class
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(),因為它沒有改變。 它只需要使用新的派生類代碼start()和stop()。
您發布的代碼應該按照您想要的方式工作。 在derived
的實例上調用doSomething
將調用在derived
定義的重寫的start
和stop
函數。
但是有一個例外。 如果你在base
的構造函數或析構函數中調用doSomething
(無論是直接還是間接),那么被調用的start
和stop
版本將是base
定義的版本。 那是因為在這種情況下,你實際上還沒有一個有效的derived
實例。 它不是完全構造的或部分破壞的,因此該語言阻止您調用將使用部分對象的方法。
如果你沒有從base
構造函數或析構函數中調用它,那么問題就比這里顯示的更多了。
更新
根據您在下面的評論,您試圖讓doSomething()調用Derived類的start()和stop()版本,我對您的問題的更新答案如下:
您定義Base和Derived的方式沒有任何問題。 您可能正在經歷所謂的“代碼切片”,您在聲明類型為“Base”的對象上調用“doSomething()”,而不是“Base *”或“Base&”,這將導致對象成為轉換為Base類型。
不好的例子:
Derived derived;
Base base = derived;
base.doSomething(); // This is Base's version of doSomething()
好例子:
Base* base = new Derived; // NOTE: declared type is "Base*"
base->doSomething(); // This will call Derived version
delete base;
注意:你應該使用scoped_ptr,shared_ptr,unique_ptr或其他一些智能指針類,而不是像我的例子那樣直接使用指針; 但是,為了不掩蓋這個問題,我選擇在這個例子中使用原始指針。 有關“切片”的更多信息,請參閱:
原始解決方案
你可以這樣做:
class Base {
public:
Base() {}
virtual ~Base() {}
virtual void start() {
startInternal();
}
virtual void stop() {
stopInternal();
}
void doSomething() {
startInternal();
// ...
stopInternal();
}
private:
void startInternal() {
// ...
}
void stopInternal() {
// ...
}
};
class Derived : public Base {
public:
Derived() {}
virtual ~Derived() {}
virtual void start() {
// ...
}
virtual void stop() {
// ...
}
};
如果你這樣做,那么doSomething()將使用未被覆蓋的內部版本的start / stop。 當構造函數/析構函數需要與虛方法共享邏輯時,您會發現很多這種模式。
此外,與手頭的問題無關,不要忘記每當創建具有虛方法的類時,都應始終創建虛擬析構函數。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.