Polymorphism - AntonioLMH/C-Tutorial GitHub Wiki
1.如果B是A的子类,B的对象就可以被当作A的对象使用。 -->Upcasting eg. Student b; Person* a =&b; Person& a = b;
Shape: class XYPos{};//x,y point class Shape{ public: Shape(); virtual ~Shape(); virtual void render(); void move(const XYPos&); virtual void resize(); protected: XYPos center; };
Ellipse: class Ellipse:public Shape{ public: Ellipse(float maj, float minr); virtual void render(); //will define own protected: float major_axis, minor_axis; };
class Circle:public Ellipse{ public: Circle(float radius): Ellipse(radius,radius){} virtual void render(); };
eg. void render(Shape* p){ p->render(); //calls correct render function } //for given shape! //p的stastic binding是Shape, dynamic binding是因为render()是virtual的。
void func(){ Ellipse ell(10,20); ell.render(); Circle circ(40); circ.render(); render(&ell);//向上造型 upcasting 实际调用ellipse 因为virtual。 render(&circ); };
Polymorphism(多态): 1.Upcast:子类被当作父类看待 2.Bing: stastic binding:code里规定了(编译时) dynamic binding: 根据object(运行时)
任意类,如果有virtual函数,这个类就比普通的大一点。 virtual 会在对象里开头加一个vptr指针(指向类的vtable,里面有所有virtual函数的地址,类里所有vptr都是一样的)。 Shape和Ellipse都会指向自己的vtable. 通过指针或引用才可以进行动态绑定!
如果函数中有一个类是virtual的,析构函数必须是virtual的。 其他oop都是动态绑定,只有C++是默认静态绑定的。
Override(覆盖): 如果父类和子类的两个函数是virtual的,名称相同,参数表也相同,他们构成override关系。
Base::func();//调用父类的函数 override的函数不能返回对象本身,只能返回指针或引用。
如果父类出现overloading的函数,子类也必须override这些函数才能保证他们不被name hidden。