c++ 多态
2015-05-30 19:04
337 查看
#include <iostream> using namespace std; //赋值兼容性原则(把子类对象赋给父类指针或引用) //函数重写 //这就是面向对象的新需求 //如果传来子类对象,那么执行子类函数 //多态 c++ 编译器提供的多态方案是虚函数 class Parent { public: Parent(int a=0) { this->a=a; } virtual void print() { cout<<"a"<<a<<endl; } private : int a; }; class Child: public Parent { public: Child(int b=0) { this->b=b; } void print() { cout<<"b"<<b<<endl; } private: int b; }; //c++ 是默认是静态编译语言,根据类型,去执行响应的函数 Parent //言外之意;:c++ 根据指针类型,去决定到具体的类里面,执行相应操作 //如果基类中加上virtual 关键字 c++ 编译器会动手脚==》动态链接编译 //c++ 编译器会来一个迟绑定 void howtoPrint(Parent *base) { base->print(); } void howtoPrint2(Parent & base) { base.print(); } void main() { Parent p1; Child c1; /*p1.print(); c1.print();*/ Parent * base=NULL; base=&p1; base->print();//打印父类的 base=&c1; base->print();//打印父类的 //p2 是c1 的别名,是c1本身 Parent & p2=c1; p2.print();//打印父类的 howtoPrint(&p1); howtoPrint(&c1); howtoPrint2(p1); howtoPrint2(c1); //以上打印父类的 system("pause"); }
</pre><pre name="code" class="cpp">
多态实例:
#include <iostream> using namespace std; class HeroFighter { public: virtual int Atack() { return 10; } protected: private: }; class EmenyFighter { public : int DesoryPower() { return 15; } }; class HeroAd2Fighter:public HeroFighter { public: int Atack() { return 20; } protected: private: }; void ObjFighter(HeroFighter * pbase,EmenyFighter * emeny ) { if(pbase->Atack()>emeny->DesoryPower()) { printf("主角win\n"); }else{ printf("主角挂了\n"); } } void main2() { HeroFighter h1; EmenyFighter e1; HeroAd2Fighter hadv; if(h1.Atack()>e1.DesoryPower()) { printf("主角win\n"); }else{ printf("主角挂了\n"); } if(hadv.Atack()>e1.DesoryPower()) { printf("主角win\n"); }else{ printf("主角挂了\n"); } system("pause"); }; void main() { HeroFighter h1; EmenyFighter e1; HeroAd2Fighter hadv; ObjFighter(&h1,&e1); ObjFighter(&hadv,&e1); };
virtual 实现多态,c++ 编译器应该动什么手脚。
第一个需要动手脚的地方 起码这个函数print 我应该动什么手脚
我怎么知道是父类对象还是子类对象?
区分是父类对象还是子类对象0
当类中声明虚函数时,编译器会在类中生成一个虚函数表。
虚函数表是一个存储类成员函数指针的数据结构
虚函数表是由编译器放入虚函数表中
存入虚函数时,每个对象中都有一个指向虚函数表的指针(vptr 指针)
#include "iostream" using namespace std; class AA { public: AA(int a= 0) { this->a = a; print(); //在构造函数里面能实现多态吗? } //分析一下要想实现多态,c++编译器应该动什么手脚 //第一个需要动手脚的地方 起码这个函数print 我应该特殊处理 virtual void print() { cout<<"父类的"<<"a"<<a<<endl; } protected: int a ; }; class BB : public AA { public: BB(int a= 0, int b = 0) { this->a = a; this->b = b; } virtual void print() { cout<<"子类的"<<"a"<<a<<"b"<<b<<endl; } private: int b ; }; void howToPrintf(AA *pBase) { //pBase 我怎么知道是父类对象还是子类对象 //动手脚2::区分是父类对象还是子类对象,提前布局 pBase->print(); // } void main() { //AA a1; BB b1; //howToPrintf(&a1); howToPrintf(&b1); system("pause"); }
#include "iostream" using namespace std; //指针也是一种数据类型,指针数据的数据类型是指,它所指的内存空间的数据类型 //最后一点引申 指针的步长 。。。c++ class Parent01 { protected: int i; int j; public: virtual void f() { cout<<"Parent01::f"<<endl; } }; class Child01 : public Parent01 { public: int k; public: Child01(int i, int j) { printf("Child01:...do\n"); } virtual void f() { printf("Child01::f()...do\n"); } }; void howToF(Parent01 *pBase) { pBase->f(); } //指针的步长 在c++领域仍然有效,父类指针的步长和子类指针的步长不一样 //多态是靠迟绑定实现的(vptr+函数指针实现) int main06() { int i = 0; Parent01* p = NULL; Child01* c = NULL; //不要把父类对象还有子类对象同事放在一个数组里面 Child01 ca[3] = {Child01(1, 2), Child01(3, 4), Child01(5, 6)}; //不要用父类指针做赋值指针变量,去遍历一个子类的数组。 p = ca; c = ca; p->f(); c->f(); //有多态发生 // p++; // c++; // // p->f();//有多态发生 // c->f(); for (i=0; i<3; i++) { howToF(&(ca[i])); } system("pause"); return 0; }
相关文章推荐
- LeetCode的medium题集合(C++实现)十七
- C++ 语法实验室之指针、常量const、字符串和等号初学误区理解
- C语言:判断一个字符串是否为十进制整数
- C++用模板求解开方(你不得不知道的模板带给我们的运行效率)
- C++ 构造与析构的执行顺序
- 【Maximum Subarray 】cpp
- C语言编程优化运行速度
- C++ 学习笔记(二) 如何向Main函数传递参数
- C语言产生随机数的方法
- c++移动语义
- char[]数组名与指针,以及字符串数组与string的一些比较
- c++ try_catch throw
- c++:不要重新定义继承而来的non-virtual函数
- 如何在Visual Studio和CodeBlocks中反编译C++代码
- C语言快速排序
- C++ 小知识点之引用:“&”
- 【Triangle 】cpp
- 关于C++类的基础
- LeetCode 199. Binary Tree Right Side View
- C语言结构体变量内存分配与地址对齐