Sean Parent:对于继承层次结构中的多态类型,具有可变对象是极端的例外

Posted

技术标签:

【中文标题】Sean Parent:对于继承层次结构中的多态类型,具有可变对象是极端的例外【英文标题】:Sean Parent: for polymorphic types in an inheritance hierarchy, having mutable object is the extreme exception 【发布时间】:2018-07-11 13:26:03 【问题描述】:

我想知道 Sean Parent 的真正含义 by this statement

对于继承层次结构中的多态类型,具有可变对象是一个极端的例外......

他接着提到了两个原因,但我无法理解他的解释。

是什么阻止我在子类中提供一个实际上改变这个对象内部结构的函数?

有人可以详细说明一下吗?

【问题讨论】:

我也在研究他的演讲!祝你好运赫马诺 我也为此 +1 有人解释一下吗? 上下文很重要! 观看视频几秒钟后,我认为这句话不应该断章取义。他似乎在谈论一种特定的技术或设计模式。此外,视频的描述说“如何在 C++ 中实现不继承的多态性”。因此,任何对此进行解释的人都应该熟悉他的演示文稿,因为它看起来确实是针对特定场景的建议,而不是笼统的“不要这样做”。 我想知道完全一样。我不知道他在说什么。当然,我很想用修改(非常量)方法来讨论设计。 【参考方案1】:

回答

在研究了一个小时的视频后 - 我明白了他的意思。

在 47:49 他开始说:

我们是否真的修改了这个对象——以及它的内部结构?一个观察结果是,对于对象的多态用例 - 具有可变对象 - 是一个极端的、极端的例外,其中有好处。这是有充分理由的。因此,如果我有一个虚函数 mutating 我的对象 - 好吗? - 那么,我正在做的是两件事之一。我要么是说我的子类可以提供不同的实现,这非常有问题,因为这将改变该操作的性能保证,并且可能会改变我的对象上的一堆其他操作,或者我是说我的子类想要观察什么时候设置了这个东西,但他们实际上并没有改变它,所以我应该做的是提供一个观察者函数,当我改变东西时我会调用它们,而不是让它们覆盖我的变异虚拟函数......

他的意思是字面意思。

...有一个虚函数变异我的对象...

因此,他说你很少有像...这样的继承等级制度

Animal
+-Cat
+-Dog
| +-Doberman
+-Bird

...您想使用具有不同实现的虚拟方法更改不同多态变体的状态(变异)。

例如

int main() 

    Animal* apObject[] =  new Cat(), new Dog(), new Doberman() ;

    const   int cnAnimals = sizeof(apObject)/sizeof(Animal*);
    for ( int i = 0; i < cnAnimals; i++ ) 
        apObject[i]->Feed(1.3);
    
    for ( int i = 0; i < cnAnimals; i++ ) 
        delete apObject[i];
    
    return 0;

所有动物都通过应用多态函数(“Feed”)来获取食物,但不同的实现对状态的修改不同。

他说这很极端,很少见!

我的评论

Sean Parent 在使用复制构造函数和赋值运算符复制多态对象时遇到了问题。在这里,如果对象是不可变的,他似乎提供了一个很好的解决方案。

但是,我认为 Sean Parents 声明“对象的多态用例 - 具有可变对象 - 是极端极端的例外”是错误的

背景: Why do we need virtual functions in C++?

引自“呆伯特原则”:

工程师识别指南

自我评估

你走进一个房间,发现一张照片挂歪了。

你……

A:拉直。

B:忽略它。

C:购买 CAD 系统 并在接下来的六个月里设计一种太阳能, 自调整相框 虽然经常大声说 你认为指甲的发明者是个彻头彻尾的白痴

正确答案是“C”,但任何在测试边缘写下“这取决于”或将整个愚蠢的事情归咎于“营销”的人都可以得到部分评分。

出于同样的原因,他的视频中有更多我不同意的陈述。

【讨论】:

以上是关于Sean Parent:对于继承层次结构中的多态类型,具有可变对象是极端的例外的主要内容,如果未能解决你的问题,请参考以下文章

继承与多态

继承与多态

继承与多态

继承与多态

在未完成的类层次结构中的“最终”类上使用虚拟继承

C++:在不违反 SRP 的情况下向多态类层次结构添加方法?