C++对象模型--2.多态

程序设计典范
1.程序模型

  以函数集作为处理的主体,如C语言程序设计方式,如下面的str*函数集:
  char boy[] = "Danny";
  char* p_son;
  ...
  p_son = new char[strlen(boy)+1];
  strcpy(p_son, boy);

2.抽象数据类型(abstract data type model,ADT)
  该模型所谓的“抽象”是和一组表达式(public 接口)一起提供,而其运算定义仍隐而未明,如下面的String Class
  String girl = "Anna";
  String daughter;
  ...

  //String::operator=()
  daughter = girl;

3.面向对象模型(object-oriented model)
  该模型是通过一个抽象的base class(用以提供通用接口)被封装起来.C++中的继承多态就是这样的。

纯粹以一种模型写程序有利于整理行为的良好稳固,如果使用混合的模型来设计就会产生语义上的歧义。比如在带有虚函数的类中,用一个对象的实力调用虚函数,让人怀疑作者是否是写错了代码,是否是应该用指向实际对象的指针或引用来调用该虚函数。但是读者又如何能排除作者就是想用对象本身来调用虚函数呢。

OO garadigm之中,程序员需要处理一个未知实体(C++中具体通过point和reference来实现),在它的继承体系中出现任何一种类型都是有可能的。原则上,这个object的真实类型在每一个执行点之前都是无法确定的。而在ADT paradigm中,程序员处理的是一个拥有固定而单一类型的实体,它在编译时期就已经完全定义好了。
多态的主要用途是经由一个共同的接口来影响类型的封装,这个接口通常被定义在一个抽象的base class中。这个共享接口是以virtual function机制引发的,它可以在执行期根据object的真正类型解析出到底是哪个函数实体被调用了。

指针的类型
一个指向整型的指针和一个指向对象的指针从内存需求的角度来说没有差别,他们的差异不在于指针表示方法不同,也不在其内容的不同,而是在其所寻址出来的object类型不同。即“指针类型”会教导编译器如何解释某个特定地址中的内存内容和其大小。
转型(cast)其实是一种编译器指令,大部分情况下它并不改变一个指针所含的地址,它只影响“被指出的内存大小及其内容”的解释方式。
多态父类指针指向子类对象的情况中该指针的类型将在编译时期决定如下两点:
    1.固定的可用接口。也就是说该指针只能调用父类的public接口;
    2.该接口的access level:public;
在每一个执行点,该指针所指向的object类型可以决定所调用的实体,类型信息的封装并不是维护于指针中,而是维护于link之中,此link存在于“object的vptr”和“vptr所指之virtual table”之间(后续会有探讨)
当一个base class object被直接初始化为一个derived class object时,derived object就会被切割(sliced),以塞入较小的base type内存中,derived type将没有留下任何蛛丝马迹,多态于是不再呈现。
一个pointer或者一个reference之所以支持多态,是因为他们并不引发内存中任何“与类型有关的内存委托操作(type-dependent commitment)”;会受到改变的只是它们所指向的内存的“大小和内容解释方式”而已。


你可能感兴趣的:(C++)