//1 指向对像的指针/*#includeusing namespace std;class father{public: father():age(52){cout<<"调用父类的构造函数并初始化age的值为:"< < jump(); p->run(); p->math(); delete p; return 0;}*///2 虚函数/*#include using namespace std;class father{public: virtual void run()const{cout<<"父亲可以跑万米"< jump(); //唉,刚才理解的大错特错了,只有是虚函数才有多态性 p->run(); //这里打印出"儿子可以跳十个台阶"?? //为什么会这样呢,这是因为函数run()前面加关键字virtual,表示该函数是有多种形态的,即该函数可以被多个对像所拥有 //而且功能不一,换句话说,多个对像在调用同一名字的函数时产生的效果也不一样,那么系统在执行到有关键字virutal的函数时 //就会自动判断是哪里个对像调用了它,然后调用该对像的同名函数 delete p; return 0;}*/// 3 拳击游戏/*#include using namespace std;class poser{public: virtual void beat()const{ cout<<"一般选手的力量为260磅"< 刘易丝<2> 泰生<3> 退出<0>"; int s; bool isexit = false; poser *p; cin>>s; switch(s) { case 1: p = new Ali(); p->beat(); break; case 2: p = new Lewis(); p->beat(); break; case 3: p = new Tyson(); p->beat(); break; case 0: isexit = true; break; default: cout<<"请输入0到3这的数字"< using namespace std;class poser{public: virtual void beat()const{ cout<<"一般选手的力量为260磅"< 刘易丝<2> 泰生<3>"; int s; cin>>s; switch(s) { case 1: p = new Ali(); break; case 2: p = new Lewis(); break; case 3: p = new Tyson(); break; default: p = new poser(); } m[i] = p; m[i]->beat(); } return 0;}*/// 4 继承是否可以实现多态性/*#include using namespace std;class A{public: virtual void print(){cout<<"A"< print(); p1->print(); p2->print(); return 0;}*///两者之间为什么会有这么显示著的区别呢?这是因为在不使用virtual之关//C++对重载的函数使用静态联编辑,而使用了virtual以后,C++则对该函数进行动态联编,//那么什么是动态联编辑,什么又是静态联编辑呢,我们先来说明一下联编//C++中的联编辑共分两种//就是静态联编辑和动态联编辑//因此在未加virtual说明时,该函数是静态联编,即被调函数和调用函数者的关系以及它闪的内存地址在编辑译时都已经确立好,运行时不再//发生变化,这样的好处是速度快,因为运行的时候不用对各个对象的函数进行追踪,只需要传递参数,执行确定好的函数并在函数调用完毕后清理内存即可//因此我们看到第一例中由于基类的print函数未说明为虚函数,则该函数在执行的时候将采用静态联编,即不对重载的各个对象的函数进行追踪//这导致C++编译器在编辑时认定的指向基类的三个指针p p1 p2在运行时也不会根据对象的改变而发生改变//因此就算是将三个对象摧存地址依次赋给了三个指针,三个指针还是默认指向基类//与其相反,动态联编辑就要牺牲一些速度,因为每个函数调用在运行前是不可确立的//要随着用户的操作来执行相应的函数,比如说在拳击游戏中用户按下一个出拳键,那么系统将根据用户选择的角色不同面彩用不同的出拳(函数)//出拳这个动作名是相同的确(函数名相同),但是他们产生的效果是不一样的, 有的拳手力量大,有的拳手力量小//(沙子数的功能不一,根据对象来定)。这个函数调用就是不可预测的,因为你无法事先预料到用户//选择的是哪些个角色,这就是代码对每个角色进行追踪,并且在游戏运行时要时该地判断该调用哪些个角色的拳头(合适的函数),然后再调用它,虽然这样比较灵活,但是相应地也就大大地增加了系统的开销,//不过在这个游戏中使用动态联编辑却是非常好的选择//在编译时的静态联编/*#include using namespace std;class A{public: int get(){return 1;}};class B: public A{public: int get(){return 2;}};int main(){ A a; int one; one = a.get(); cout<<"a的值是:"< < using namespace std;class A{public: int get(){return 1;}};class B: public A{public: int get(){return 2;}};int main(){ while(1) { cout<<"(1)父类 (2)子类 (3)退出"; int s; cin>>s; A *p; bool quit = false; switch(s) { case 1: p = new A; cout< get()< get()< get()< using namespace std;class A{public: virtual int get(){return 1;}};class B: public A{public: int get(){return 2;}};int main(){ while(1) { cout<<"(1)父类 (2)子类 (3)退出"; int s; cin>>s; A *p; bool quit = false; switch(s) { case 1: p = new A; cout< get()< get()< get()< using namespace std;class A{public: virtual int get(){return 1;}};class B: public A{public: int get(){return 2;}};int main(){ while(1) { cout<<"(1)父类 (2)子类 (3)退出"; int s; cin>>s; A p; bool quit = false; switch(s) { case 1: p = A(); cout< < using namespace std;class father{public: virtual void run()const{cout<<"父亲可以跑万米\n";}};class son:public father{public: void run()const{cout<<"儿子可以跑十万米\n";}};class daughter:public father{public: void run()const{cout<<"女儿可以跑五万米\n";}};void One(father one);void Tow(father *two);void Three(father &three);int main(){ father *p; int s; bool quit = false; while(1) { cout<<"(1)父亲 (2)儿子 (3)女儿 (0)退出"< >s; switch(s){ case 1: p = new father; Three(*p); break; case 2: p = new son; One(*p); break; case 3: p = new daughter; Tow(p); break; case 0: quit = true; break; default: cout<<"参数不正确!"; break; } if(quit == true){ break; } } return 0;}void One(father one){ one.run();}void Tow(father *two){ two->run();}void Three(father &three){ three.run();}*///////系统是如何调用虚函数的/*每个对象创建虚函数时,对象都得记录这个虚函数,因此编译器建立了一个叫做T表的虚函数表每个对象都有一个指向该表的指针,叫做虚表指针,该指针用来指向虚函数表,相反虚函数表也有一个指针指向该对象当创建派生类对象的基类部分时,该对象的指针就自动初始化为指向虚函数表的正确部分,当调用派生类对象的构造函数时这个对象就会添加到虚函数表中去,并且将指针指向该对象的重载函数当使用指向基类的指针时,将根据对象的实际类型,将该对象的指针继续指向正确的函数*//*#include using namespace std;class A{public: virtual int get(){ return 0;}};class B : public A{public: int get(){ return 1;}};int main(){ B b; B *p = &b; //这就是动态联编,两种实例化是一样的 //A *p = &b; cout< get()< A::get()< using namespace std;class A{public: A(){cout<<"创建A"< func(); delete p; return 0;}