tri*_*ta2 6 c++ polymorphism inheritance
大编辑
因此,在收集了所有人的反馈意见,并按照Zack的建议冥想XY问题后,我决定添加另一个代码示例,该示例说明了我正在努力完成的事情(即"X"),而不是询问我的" Y".
所以,现在我们正在与汽车工作,我已经添加了5抽象类:ICar,ICarFeatures,ICarParts,ICarMaker,ICarFixer.所有这些接口都将包装或使用第三方库提供的特定于技术的复杂对象,具体取决于接口背后的派生类.这些接口将智能地管理复杂库对象的生命周期.
我的用例是FordCar类.在这个例子中,我用了福特库访问班FordFeatureImpl,FordPartsImpl和FordCarImpl.这是代码:
class ICar {
public:
ICar(void) {}
virtual ~ICar(void) {}
};
class FordCar : public ICar {
public:
ICar(void) {}
~FordCar(void) {}
FordCarImpl* _carImpl;
};
class ICarFeatures {
public:
ICarFeatures(void) {}
virtual ~ICarFeatures(void) {}
virtual void addFeature(UserInput feature) = 0;
};
class FordCarFeatures : public ICarFeatures{
public:
FordCarFeatures(void) {}
virtual ~FordCarFeatures(void) {}
virtual void addFeature(UserInput feature){
//extract useful information out of feature, ie:
std::string name = feature.name;
int value = feature.value;
_fordFeature->specialAddFeatureMethod(name, value);
}
FordFeatureImpl* _fordFeature;
};
class ICarParts {
public:
ICarParts(void) {}
virtual ~ICarParts(void) {}
virtual void addPart(UserInput part) = 0;
};
class FordCarParts :public ICarParts{
public:
FordCarParts(void) {}
virtual ~FordCarParts(void) {}
virtual void addPart(UserInput part) {
//extract useful information out of part, ie:
std::string name = part.name;
std::string dimensions = part.dimensions;
_fordParts->specialAddPartMethod(name, dimensions);
}
FordPartsImpl* _fordParts;
};
class ICarMaker {
public:
ICarMaker(void) {}
virtual ~ICarMaker(void) {}
virtual ICar* makeCar(ICarFeatures* features, ICarParts* parts) = 0;
};
class FordCarMaker {
public:
FordCarMaker(void) {}
virtual ~FordCarMaker(void) {}
virtual ICar* makeCar(ICarFeatures* features, ICarParts* parts){
FordFeatureImpl* fordFeatures = dynamic_cast<FordFeatureImpl*>(features);
FordPartsImpl* fordParts = dynamic_cast<FordPartsImpl*>(parts);
FordCar* fordCar = customFordMakerFunction(fordFeatures, fordParts);
return dynamic_cast<ICar*>(fordCar);
}
FordCar* customFordMakerFunction(FordFeatureImpl* fordFeatures, FordPartsImpl* fordParts) {
FordCar* fordCar = new FordCar;
fordCar->_carImpl->specialFeatureMethod(fordFeatures);
fordCar->_carImpl->specialPartsMethod(fordParts);
return fordCar;
}
};
class ICarFixer {
public:
ICarFixer(void) {}
virtual ~ICarFixer(void) {}
virtual void fixCar(ICar* car, ICarParts* parts) = 0;
};
class FordCarFixer {
public:
FordCarFixer(void) {}
virtual ~FordCarFixer(void) {}
virtual void fixCar(ICar* car, ICarParts* parts) {
FordCar* fordCar = dynamic_cast<FordCar*>(car);
FordPartsImpl* fordParts = dynamic_cast<FordPartsImpl*>(parts);
customFordFixerFunction(fordCar, fordParts);
}
customFordFixerFunction(FordCar* fordCar, FordPartsImpl* fordParts){
fordCar->_carImpl->specialRepairMethod(fordParts);
}
};
Run Code Online (Sandbox Code Playgroud)
请注意,我必须使用动态强制转换来访问抽象接口中特定于技术的对象.这就是让我觉得我滥用继承并激怒我最初问这个问题的原因.
这是我的最终目标:
UserInput userInput = getUserInput(); //just a configuration file ie XML/YAML
CarType carType = userInput.getCarType();
ICarParts* carParts = CarPartFactory::makeFrom(carType);
carParts->addPart(userInput);
ICarFeatures* carFeatures = CarFeaturesFactory::makeFrom(carType);
carFeatures->addFeature(userInput);
ICarMaker* carMaker = CarMakerFactory::makeFrom(carType);
ICar* car = carMaker->makeCar(carFeatures, carParts);
UserInput repairSpecs = getUserInput();
ICarParts* replacementParts = CarPartFactory::makeFrom(carType);
replacementParts->addPart(repairSpecs);
ICarFixer* carFixer = CarFixerFactory::makeFrom(carType);
carFixer->fixCar(car, replacementParts);
Run Code Online (Sandbox Code Playgroud)
也许现在你们都对我正在尝试做的事情有了更好的理解,也许我可以改进.
我正在尝试使用基类的指针来表示派生(即Ford)类,但派生类包含FordPartsImpl其他派生类(即FordCarFixer需要a FordCar和FordPartsImplobject)所需的特定对象(即).这需要我使用动态转换来将指针从基础向下转换到其各自的派生类,以便我可以访问这些特定的Ford对象.
这不是滥用继承...这是滥用继承
class CSNode:public CNode, public IMvcSubject, public CBaseLink,
public CBaseVarObserver,public CBaseDataExchange, public CBaseVarOwner
Run Code Online (Sandbox Code Playgroud)
其中那些带有 C 前缀的人有巨大的实现
不仅如此...标头有超过 300 行声明。
所以不......你现在没有滥用继承权。
但我刚刚向您展示的这个类是侵蚀的产物。我确信 Node 一开始就是一个闪亮的灯塔和多态性,能够在行为和节点之间智能切换。
现在它已经变成了海怪、巨蛾、克苏鲁本身,只用它的幻象就试图咀嚼我的内脏。
留意这个自由人,留意我的忠告,当心你的多态性可能会变成什么样子。
否则,这很好,继承的一个很好的用途,我认为是尿布中的架构。
单一工作方法...您可以尝试:
但你的继承似乎是正确的,每个人都会使用的单一方法。
还有一件事......我只是要把这个维基链接留在这里
或者也许只是复制粘贴 wiki C++ 代码...这与您的非常相似:
#include <iostream>
#include <string>
template <typename OutputPolicy, typename LanguagePolicy>
class HelloWorld : private OutputPolicy, private LanguagePolicy
{
using OutputPolicy::print;
using LanguagePolicy::message;
public:
// Behaviour method
void run() const
{
// Two policy methods
print(message());
}
};
class OutputPolicyWriteToCout
{
protected:
template<typename MessageType>
void print(MessageType const &message) const
{
std::cout << message << std::endl;
}
};
class LanguagePolicyEnglish
{
protected:
std::string message() const
{
return "Hello, World!";
}
};
class LanguagePolicyGerman
{
protected:
std::string message() const
{
return "Hallo Welt!";
}
};
int main()
{
/* Example 1 */
typedef HelloWorld<OutputPolicyWriteToCout, LanguagePolicyEnglish> HelloWorldEnglish;
HelloWorldEnglish hello_world;
hello_world.run(); // prints "Hello, World!"
/* Example 2
* Does the same, but uses another language policy */
typedef HelloWorld<OutputPolicyWriteToCout, LanguagePolicyGerman> HelloWorldGerman;
HelloWorldGerman hello_world2;
hello_world2.run(); // prints "Hallo Welt!"
}
Run Code Online (Sandbox Code Playgroud)
更重要的问题是
您当前的实现将无法处理该问题
有政策就有可能。
帮助您定义是否需要这种行为
也许你的模型永远不会随着时间的推移而真正改变。
| 归档时间: |
|
| 查看次数: |
809 次 |
| 最近记录: |