I wrote a program that uses virtual functions to achieve polymorphism. I have a main user class that blindly calls a method, which in its opinion is common objects (although they really need to be specialized). These objects belong to classes that override pure virtual functions in their base classes. The following adapted code should demonstrate my setup:
Generic class (BaseConfig) in BaseConfig.h:
class BaseConfig { public: ... virtual void display() const = 0; ... }
A specialized version of the above general class (SpecialConfig) in SpecialConfig.h:
class SpecialConfig : public BaseConfig { public: ... void display() const; ... }
Implementation of the above specialized class in SpecialConfig.cpp:
... void SpecialConfig::display() const {
Now, when I create the BaseConfig pointer and set it to the address of the SpecialConfig object, calling display () calls the display () function of the SpecialConfig class, as expected. However, things disagree with what I expect in the following code snippets to such an extent that for some reason, after the SpecialConfig objects return to the BaseConfig queue, calling the display () function no longer hits the display function () in SpecialConfig but instead tries to use the display () function in BaseConfig, causing the program to exit.
Here is a general class for generating configuration permutations. We will call it BaseRuleSet in BaseRuleSet.h:
class BaseRuleSet { public: ... virtual queue<BaseConfig *> getValidChildConfigurations(BaseConfig * c) const = 0; ... }
The getValidChildConfigurations function will be overridden in the specialized RuleSet classes, as shown in the SpecialRuleSet class from SpecialRuleSet.h:
class SpecialRuleSet : public BaseRuleSet { public: ... queue<BaseConfig *> getValidChildConfigurations(BaseConfig * c) const; }
Implementation of the above class in 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);
As shown in the comment above, polymorphism is still working correctly at this point, since the specialized display function is still falling. However, in this last piece of code (shown below) everything falls apart. This is the User class from User.cpp:
... void User::doStuff() { BaseRuleSet * baseRuleSet; SpecialRuleSet specialRuleSet; baseRuleSet = &specialRuleSet; BaseConfig * currentConfig; queue<BaseConfig *> childConfigurations = ruleSet->getValidChildConfigurations(currentConfig); childConfigurations.front()->display();
As the last comment in the above example shows, the last call to display () actually tries to use a pure virtual function in BaseConfig instead of the embedded custom version in SpecialConfig.
My thoughts are either a limitation or another way of doing things in C ++ that I donβt know about, or there are errors in my implementation. Can someone help clarify this for me?
Thanks.