c++ 多态

#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;
}




评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值