我读到“混凝土类型很少作为进一步推导的基础”------------ Stroustrup p。 768
如何解释这个?这是否意味着我们应该使用纯虚函数从基类中获取派生类?但是,我看到很多代码都是派生类派生自具体类型的。
任何人都可以帮助我吗?
答案 0 :(得分:3)
答案 1 :(得分:3)
假设您创建了一个派生类,然后用该派生类替换程序中基类的每个实例。结果程序的行为是否相同?如果没有,那么你已经介绍了一些陷阱。在为继承而设计的类的情况下,可能会考虑这些问题(例如,我已经看到一些为继承而设计的类,实际上有一些函数来检查是否实现了其他函数以允许它们甚至不存在,例如文件可能缺少的I / O类寻求功能)。由于抽象类总是在设计时考虑了继承,但具体类可能不会,这可能是不安全的。
上面的解释讨论了结果派生类与基类不完全兼容的情况,这是危险的。但是,如果 完全兼容呢?在这种情况下,使用继承(而不是组合)的一些潜在justifications会分崩离析。我们没有任何虚函数或受保护的成员(如果我们做,那么我假设该类是为继承而设计的)。尽管如此,在这种情况下使用继承可能非常安全,但确保它真正完全兼容是很困难的。我宁愿使用作文并且安全。
修改:
我上面谈到的术语是Liskov Substitution Principle。一个较短的解释是,在大多数情况下,不是为继承而设计的类的派生类将违反Liskov的替换原则,或者无法完成任何使用合成无法完成的任何有用的东西。
答案 2 :(得分:1)
这是另一种说法“继承被重用,而不是重用”。从具体类开始,通常会重复使用该类中的一些代码,这是(现在)不满意的。
答案 3 :(得分:1)
这里的问题是混淆类的具体类型。像往常一样,Stroustrup将抽象类定义为无法实例化的类,因为它具有纯虚拟成员函数,即它没有完整的实现;因此,具体类只是一个可以实例化的非抽象类。 OTOH,一种具体的类型“是一个相对简单的概念的代表,所有操作都支持这个概念。......具体类型类似于内置类型。当然,内置类型都是具体的。” Stroustrup p。 766
答案 4 :(得分:0)
这里的想法是,您不应该继承int
,float
或std::string
等类型。无论如何,您都不会从int foo(int a)
获得OO行为。即使对于int foo(std::string&)
,std::string
中缺少虚函数也意味着foo
不会调用您的替代。