十四、C++ 多态

1.多态定义

之所以引入虚函数,是为了引入多态

多态就是使用相同的调用方法,对不同的对象,它会调用不同类里面实现的函数

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Human {
public:
	void eating(void) { cout<<"use hand to eat"<<endl; }
};

class Englishman : public Human {
public:
	void eating(void) { cout<<"use knife to eat"<<endl; }
};


class Chinese : public Human {
public:
	void eating(void) { cout<<"use chopsticks to eat"<<endl; }
};

void test_eating(Human& h)
{
	h.eating();
}

int main(int argc, char **argv)
{
	Human h;
	Englishman e;
	Chinese c;

	test_eating(h);
	test_eating(e);
	test_eating(c);

	return 0;
}

运行结果:
use hand to eat
use hand to eat
use hand to eat

2.虚函数

应该在 test_eating 中分辨它属于哪一个对象,是英国人还是中国人,让系统编译器帮忙分辨

Human中的 eating 加上virtual 变成虚函数

派生类继承它,也就变成了虚函数,可以加 virtual,也可以不加 virtual

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Human {
private:
	int a;
public:
	virtual void eating(void) { cout<<"use hand to eat"<<endl; }
    //虚函数
};

class Englishman : public Human {
public:
	void eating(void) { cout<<"use knife to eat"<<endl; }
    //继承之后也变成了虚函数
};


class Chinese : public Human {
public:
	void eating(void) { cout<<"use chopsticks to eat"<<endl; }
};

void test_eating(Human& h)
{
	h.eating();
}

int main(int argc, char **argv)
{
	Human h;
	Englishman e;
	Chinese c;

	test_eating(h);
	test_eating(e);
	test_eating(c);

	cout<<"sizeof(Human) = "<<sizeof(h)<<endl;
	cout<<"sizeof(Englishman) = "<<sizeof(e)<<endl;
	cout<<"sizeof(Chinese) = "<<sizeof(c)<<endl;

	return 0;
}

执行结果:
use hand to eat
use knife to eat
use chopsticks to eat

静态联编:如果不是 virtual虚函数,test_eating 在编译的时候就确定好 h.eating 调用哪一个类里面的 eating函数,

动态联编:在运行的时候才知道调用哪一个函数

 3.使用引用指针来使用对象时,才有多态;传值时,无多态

使用引用指针来使用对象时,才有多态;传值时,无多态       

        a.只有类的成员函数才能声明为虚函数

        b.静态成员函数不能是虚函数

        c.内联函数不能是虚函数

        d.构造函数不能是虚函数

        e.析构函数一般声明为虚函数

        f.重载:函数参数不同,不能设为虚函数

        覆写:函数参数、返回值相同,可以设为虚函数

        g.返回值例外

        函数参数相同,但是返回值是当前对象的指针或引用时,也可以设为虚函数

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Human {
private:
	int a;
public:
	virtual void eating(void) { cout<<"use hand to eat"<<endl; }
};

class Englishman : public Human {
public:
	void eating(void) { cout<<"use knife to eat"<<endl; }
};


class Chinese : public Human {
public:
	void eating(void) { cout<<"use chopsticks to eat"<<endl; }
};

void test_eating(Human h)
{
	h.eating();
}

int main(int argc, char **argv)
{
	Human h;
	Englishman e;
	Chinese c;

	test_eating(h);
	test_eating(e);
	test_eating(c);

	cout<<"sizeof(Human) = "<<sizeof(h)<<endl;
	cout<<"sizeof(Englishman) = "<<sizeof(e)<<endl;
	cout<<"sizeof(Chinese) = "<<sizeof(c)<<endl;

	return 0;
}


运行结果:
use hand to eat
use hand to eat
use hand to eat

强制转化之后,就只剩下基类部分,没有指针了,所以传值时候只能使用静态联编

4.析构函数一般声明为虚函数

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Human {
private:
	int a;
public:
	virtual void eating(void) { cout<<"use hand to eat"<<endl; }
	virtual ~Human() { cout<<"~Human()"<<endl; }
};

class Englishman : public Human {
public:
	void eating(void) { cout<<"use knife to eat"<<endl; }
	virtual ~Englishman() { cout<<"~Englishman()"<<endl; }
};


class Chinese : public Human {
public:
	void eating(void) { cout<<"use chopsticks to eat"<<endl; }
	virtual ~Chinese() { cout<<"~Chinese()"<<endl; }
};

void test_eating(Human h)
{
	h.eating();
}

int main(int argc, char **argv)
{
	Human* h = new Human;
	Englishman* e = new Englishman;
	Chinese* c = new Chinese;

	Human *p[3] = {h, e, c};
	int i;

	for (i = 0; i < 3; i++)
	{
		p[i]->eating();
		delete p[i];
	}


	return 0;
}

5.返回值例外

函数参数相同,但是返回值是当前对象的指针或引用时,也可以设为虚函数

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Human {
private:
	int a;
public:
	virtual void eating(void) { cout<<"use hand to eat"<<endl; }
	virtual ~Human() { cout<<"~Human()"<<endl; }
	virtual void test(void) {cout<<"Human's test"<<endl; }
};

class Englishman : public Human {
public:
	void eating(void) { cout<<"use knife to eat"<<endl; }
	virtual ~Englishman() { cout<<"~Englishman()"<<endl; }
	virtual int test(void) {cout<<"Englishman's test"<<endl; return 1; }
};


class Chinese : public Human {
public:
	void eating(void) { cout<<"use chopsticks to eat"<<endl; }
	virtual ~Chinese() { cout<<"~Chinese()"<<endl; }
	virtual int test(void) {cout<<"Chinese's test"<<endl; return 1; }
};

void test_eating(Human& h)
{
	h.eating();
}

void test_return(Human& h)
{
	h.test();
}



int main(int argc, char **argv)
{
	Human h;
	Englishman e;
	Chinese c;

	test_return(h);
	test_return(e);
	test_return(c);


	return 0;
}

返回值不是指针且不同,编译不能通过

#include <iostream>
#include <string.h>
#include <unistd.h>

using namespace std;

class Human {
private:
	int a;
public:
	virtual void eating(void) { cout<<"use hand to eat"<<endl; }
	virtual ~Human() { cout<<"~Human()"<<endl; }
	virtual Human* test(void) {cout<<"Human's test"<<endl; return this; }
};

class Englishman : public Human {
public:
	void eating(void) { cout<<"use knife to eat"<<endl; }
	virtual ~Englishman() { cout<<"~Englishman()"<<endl; }
	virtual Englishman* test(void) {cout<<"Englishman's test"<<endl; return this; }
};


class Chinese : public Human {
public:
	void eating(void) { cout<<"use chopsticks to eat"<<endl; }
	virtual ~Chinese() { cout<<"~Chinese()"<<endl; }
	virtual Chinese* test(void) {cout<<"Chinese's test"<<endl; return this; }
};

void test_eating(Human& h)
{
	h.eating();
}

void test_return(Human& h)
{
	h.test();
}



int main(int argc, char **argv)
{
	Human h;
	Englishman e;
	Chinese c;

	test_return(h);
	test_return(e);
	test_return(c);


	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值