C++ 多态小示例
#include <string.h> #include <iostream> using namespace std; class Employee{ protected : char name[20]; public: Employee(const char *str){ strcpy(this->name,str); } virtual void display(){ cout<<"Employee::display()"<<endl; } void fun_nonvirtual(){ cout<<"Employee::fun_nonvirtual()"<<endl; } }; class Manager:public Employee{ private: int deptId; public: Manager(const char *str):Employee(str){ this->deptId=0; } void display(){ cout<<"Manager::display(), "<<"name = " <<name<<endl; } void fun_nonvirtual(){ cout<<"Manager::fun_nonvirtual()"<<endl; } void xxx(){ cout<<"Manager::xxx(), "<<this->deptId<<endl; } }; int main(){ cout<<sizeof(Manager)<<endl; //sizeof(Manager) = 28 , 20+4+4(name+deptId+vptr) Employee *pe1; Manager m1("张三"); pe1=&m1; pe1->display(); //Manager::display() 多态(指针或引用+虚函数) pe1->fun_nonvirtual(); //Employee::fun_nonvirtual() 指针pe1声明类型为Employee Employee e2=m1; //拷贝构造函数负责将对象e2的vptr指向类型Employee的vtable e2.display(); //vtable之display指向Employee::display() Employee e1("张九"); Manager *pm; pm=(Manager*)(&e1); //需要强制类型转化,否则编译不通过 pm->xxx(); //打印出deptId为乱码 return 0; }
注意事项
1、虚函数派生下去仍为虚函数,而且可以省略virtual关键字;
2、派生类会继承基类的虚函数表,当我们在派生类中改写虚函数时,虚函数表就受到影响:表中元素所指的函数地址将不再是基类的函数地址,而是派生类的函数地址;
3、以单一指令调用不同函数,就是多态;
4、一个“基类之指针”指向“派生类之对象”,那么经由该指针你只能调用基类所定义的函数(虚函数除外);
5、以一个“派生类之指针”指向一个“基类之对象”,必须先做明显的转型操作(explicit cast),这种做法存在危险;
浙公网安备 33010602011771号