我寫了一個使用虛函數實現多態的程序。我有一個主要的User類,它盲目地調用它認爲是通用對象的方法(儘管它們實際上應該是專用的)。這些對象來自覆蓋其基類中純虛函數的類。下面的代碼調整應當證明我的設置:多態實現問題
在BaseConfig.h泛型類(BaseConfig):
class BaseConfig {
public:
...
virtual void display() const = 0;
...
}
上述泛型類(SpecialConfig)的SpecialConfig.h專門版本:
class SpecialConfig : public BaseConfig {
public:
...
void display() const;
...
}
以上專業類的SpecialConfig.cpp實施:
...
void SpecialConfig::display() const {
// print some text
}
...
現在,當我創建BaseConfig指針並將其設置爲SpecialConfig對象的地址時,調用display()將按照它的設想擊中SpecialConfig類的display()函數。但是,與以下代碼片段中我所期望的不同的是,出於某種原因,在SpecialConfig對象返回BaseConfig隊列後,對它們調用display()函數不再會觸發SpecialConfig中的display()函數而是嘗試在BaseConfig中使用display()函數,導致程序退出。
這是一個用於生成配置排列的通用類。我們叫它BaseRuleSet在BaseRuleSet.h:
class BaseRuleSet {
public:
...
virtual queue<BaseConfig *> getValidChildConfigurations(BaseConfig * c) const = 0;
...
}
其getValidChildConfigurations功能將在專用規則集類中重寫如圖所示類SpecialRuleSet從SpecialRuleSet.h:
class SpecialRuleSet : public BaseRuleSet {
public:
...
queue<BaseConfig *> getValidChildConfigurations(BaseConfig * c) const;
}
的實施在SpecialRuleSet.cpp上面的類:
...
queue<BaseConfig *> SpecialRuleSet::getValidChildConfigurations(BaseConfig * c) const {
queue<BaseConfig *> validChildConfigurations;
BaseConfig * baseConfigA;
BaseConfig * baseConfigB;
SpecialConfig specialConfigA;
SpecialConfig specialConfigB;
baseConfigA = &specialConfigA;
baseConfigB = &specialConfigB;
validChildConfigurations.push(baseConfigA);
validChildConfigurations.push(baseConfigB);
// validChildConfigurations.front()->display() works correctly here
return validChildConfigurations;
}
...
如上註釋所示,多態性仍然正確地在這一點上,因爲工作專門的顯示功能仍在被擊中。但是,在最後的代碼片段中(如下所示),一切都崩潰了。這是從User.cpp User類:
...
void User::doStuff() {
BaseRuleSet * baseRuleSet;
SpecialRuleSet specialRuleSet;
baseRuleSet = &specialRuleSet;
BaseConfig * currentConfig;
/*
SpecialConfig specialConfig;
currentConfig = &specialConfig;
currentConfig->display(); // this works
*/
queue<BaseConfig *> childConfigurations = ruleSet->getValidChildConfigurations(currentConfig);
childConfigurations.front()->display(); // this does not work
}
作爲最後一個註釋示出了在上面的例子中,在最後一次調用到顯示()實際上嘗試使用純虛函數在BaseConfig代替實施專門版本在SpecialConfig中。
我的想法是在C++中存在一種限制或不同的方式,我不知道或者在實現中存在錯誤。任何人都可以幫我澄清這一點嗎?
謝謝。
getValidChildConfigurations返回指向函數完成後不存在的對象的指針。 – bmm6o 2012-01-16 19:30:10