您的位置:首页 > 编程语言 > C语言/C++

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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: