C++ C+的优雅解决方案+;多态遗传问题
想象一下,我们正在使用的图书馆有两个类:Dog和BowlC++ C+的优雅解决方案+;多态遗传问题,c++,inheritance,polymorphism,C++,Inheritance,Polymorphism,想象一下,我们正在使用的图书馆有两个类:Dog和Bowl class Bowl; class Dog { Bowl* m_bowl; }; class Bowl { Dog* m_owner; }; 狗拥有一个指向其关联碗对象的指针。Bowl还拥有一个指向其关联Dog对象的指针。一切都很好。现在,我派生了一个新类FancyDog,它扩展了Dog的功能 class FancyDog : public Dog { // Do the fancy dog stuff }
class Bowl;
class Dog
{
Bowl* m_bowl;
};
class Bowl
{
Dog* m_owner;
};
狗拥有一个指向其关联碗对象的指针。Bowl还拥有一个指向其关联Dog对象的指针。一切都很好。现在,我派生了一个新类FancyDog,它扩展了Dog的功能
class FancyDog : public Dog
{
// Do the fancy dog stuff
};
一切都很好,至少在FancyDog需要用一个新的闪亮豪华的碗来替换她那无聊的、旧的普通碗之前是这样
class FancyBowl : public Bowl
{
// Extra functions only relevant for FancyBowls
};
FancyDog应该如何与其新的FancyBowl交互?我只能想到两个选择,两个都“不错”,但都不是很令人满意
请注意,如果我们试图让FancyBowl跟踪狗,我们也会遇到同样的问题。这是狗/碗作者设计不佳的问题。考虑下面的改进:
class Bowl;
class Dog
{
virtual Bowl* getBowl() = 0;
};
class Bowl
{
Dog* m_owner;
};
现在,FancyDog的一个实现可以保存一个FancyBowl并返回一个指向它的指针,这没有问题
本质上,问题在于差异——因为Dog类保留了分配给m_bowl
指针的权利,所以不能保证它总是指向FancyBowl,因为Dog可能会重新分配它。在第一种情况下,您保证FancyDog始终有一个FancyBowl,但是您失去了狗和FancyDog看到同一个碗的保证。在第二种情况下,你不知道碗会是一个花式猫头鹰,但你知道你至少总是使用同一个碗
如果Dog类声明了一个更简单的接口,该接口只需要类实际需要的内容(即,您有一个碗可供它读取),那么问题就消失了。如果您不喜欢简单的运行时多态getter,那么上面还有更复杂的静态变体。不要使用原始指针是我能给出的最贴切的建议。FancyBowl是Bowl的孩子。让任何需要区分Bowl和FancyBowl的方法都是虚拟的有什么不对?这样,您只需保证FancyDog对象是使用/给定FancyBowl指针构造的。老实说,这种设计更像是没有正确地进行抽象。也许简单继承无法正确地建模这种关系。狗可以在它的碗上专门化,并假设它至少有
碗的接口。@πάνταῥεῖ 我查看了原始指针,但所有权/生命周期不是这里的问题。非常清楚的解释,谢谢!在我的特殊情况下,改变图书馆需要做很多工作,但我确实学到了很多+你的名字太相关了!你有没有可能为你提到的静态变量提供一个链接或搜索关键字,这样我就可以快速查看一下,看看我是否能理解它?