今天学习了 c++ 的类和多态性内容,有一点感想,想写下来 首先想说说父类和子类的关系。我假设现在又一个父类 Animal,一个子类Fish 我们知道,当我们新建一个子类Fish的时候,会调用它的构造函数Fish();不过在调用Fish()之前,编译器又回先调用它的父类Animal的构造函数。当调用完Animal的构造函数后,再调用子Fish的构造函数。道理很简单,没有父亲哪有儿子。然后我们看看此时Fish对象在内存中的情况:
所以我们可以把fish的指针付给animal,fish指针只能指向属于animal的部分。但掉转把animal指针付给fish就不行了。原因是fish指针能访问的范围比animal大,有可能访问到不属于animal以外的部分。
下面假设有这样的情况,animal有一个public方法show(): class animal { public: void show(){ cout<<"I'm animal"<<endl;} }; 而我fish类重写了show()方法: class fish { public: void show() { cout<<"I'm fish"<<endl;} } 当我在main()函数中添加下面的语句时,会输出什么呢? void main() { fish child; animal* pfather; pfather=child; pfather->show(); system("pause"); } 答案是 "I'm animal" 也就是说调用了父类animal的show()方法,而不是子类的,虽然我们把子类的地址付给了父类。为什么会出现这种情况呢?这就涉及两个概念,静态绑定和动态绑定了。 静态绑定指的是当程序编译时,就指定了要调用哪个函数。 动态绑定指的是程序在编译的时候不指定调用哪个函数,而是到了程序运行时才决定调用哪个函数。 所以以上代码才会产生这样的结果。那我们如何才能实现调用子类fish的show()方法呢? 那就是用动态绑定。具体方面就是在父类的show()方法前面添加一个说明符virtual,使该函数成为一个虚函数。当编译器遇到virtual时,并不对函数进行静态绑定,而是到了程序运行时才根据指针类型绑定相应的函数。
下面就让我联想到C#中实现多态的方法。 1.c#中我们可以定义利用abstract定义抽象方法,然后让子类继承并补充代码。 2.类似c++中的方法,把父类中的函数定义为virtual,然后在子类中用override重写函数(注意一定要用override重写) |
c++ 多态性 (附加与c#多态性的联想)
2010-09-09 18:35