绝大多数C++程序员都熟悉面向对象编程这一概念,继承、多态和动态绑定(dynamic binding)。然而,C++还支持其它有用的典范,例如基于对象的编程(object-based programming)。
基于对象的编程依赖我们所熟悉的概念,如重载、封装和抽象数据类型。然而,与面相对象编程不同,在基于对象的编程中,并没有继承和动态绑定这两个概念。
我们常常把用基于对象编程概念所实现的类叫着具体类(concrete class)。http://ct.com.com/click?q=96-pjrWQtdedRNnkLebBf.oGEPT0m3n给出了有关这种编程典范的演示。
所有的STL容器类都有一个共同的特点:没有虚的解析函数。这样做是有深意的,而不是出于什么疏忽。
由于没有虚解析函数,就消除了动态绑定所花费的开销。此外,当解析函数不是虚函数时,编译器可以更容易的内联(inline)。但这个特性可能产生问题。如果某个类的解析函数不是一个虚函数时,那么把这个类作为另一个类的基类至少是一个冒险的举动。让我们看看为什么会这样。
当你使用公共继承时,你可以在基类和子类之间创建一个is-a关系。因此,指向基类的指针或者对基类的引用可能对它的子类对象起作用。如果基类的解析函数非虚,C++将无法调用上下文中的解析函数链。例如:
class Concrete
{
public:
~Concrete() {} //解析函数不是虚函数
};
class Polymorphic: public Concrete // 这可不是个好主意
{
public:
~ Polymorphic () {}
};
int main()
{
Concrete * p = new Polymorphic; //看起来似乎没有问题
delete p; //没有调用多态的解析函数!!!
}
由于没有调用对象的解析函数,将会导致未知的行为。因此,你不应该从具体类(如std::string和std::vector)中导出新的类。缺乏虚的解析函数意味着这些类不能作为其它类的基类。
本文作者Danny Kalev 是一个系统分析家、软件工程师,在C++和面向对象设计方面有着14年的专业经验。