多态的基本概念

基类指针可以指向派生类对象,但是通过基类指针只能调用基类的成员函数,访问基类的成员变量,不能调用派生类的成员函数,也不能访问访问派生类的成员变量。

#include<iostream>
using namespace std;
class CAllComers{
public:
	int m_bh=0;
	void show(){
		cout<<"CAllComers::show()我是"<<m_bh<<"号。"<<endl; 
	}
}; 
class CGirl:public CAllComers{
public:
	int m_age=0;
	void show(){
		cout<<"CGirl::show():我是"<<m_bh<<"号,"<<m_age<<"岁。"<<endl; 
	}
};
int main(){
    CGirl g;
	g.m_bh=8;
	g.m_age=23;
	g.show();
	CAllComers*pa=&g;
	pa->show();	
	
	
	return 0;
} 
CGirl::show():我是8号,23岁。
CAllComers::show()我是8号。

--------------------------------
Process exited after 0.518 seconds with return value 0
请按任意键继续. . .

如果基类函数是虚函数,当用基类指针指向派生对象时,会调用派生类中同名的成员函数。

:在基类的show()成员函数前加virtual关键字,把他声明为虚函数-----再运行:

#include<iostream>
using namespace std;
class CAllComers{
public:
	int m_bh=0;
	virtual void show(){
		cout<<"CAllComers::show()我是"<<m_bh<<"号。"<<endl; 
	}
}; 
class CGirl:public CAllComers{
public:
	int m_age=0;
	void show(){
		cout<<"CGirl::show():我是"<<m_bh<<"号,"<<m_age<<"岁。"<<endl; 
	}
};
int main(){
    CGirl g;
	g.m_bh=8;
	g.m_age=23;
	g.show();
	CAllComers*pa=&g;
	pa->show();	
	
	
	return 0;
} 
CGirl::show():我是8号,23岁。
CGirl::show():我是8号,23岁。

--------------------------------
Process exited after 0.5126 seconds with return value 0
请按任意键继续. . .

如果基类函数是虚函数,当用基类指针指向派生对象时,会调用派生类中同名的成员函数。

通过派生类中同名的成员函数,就可以访问派生类对象的成员变量。

 

#include<iostream>
using namespace std;
class CAllComers{
public:
	int m_bh=0;
	virtual void show(){
		cout<<"CAllComers::show()我是"<<m_bh<<"号。"<<endl; 
	}
}; 
class CGirl:public CAllComers{
public:
	int m_age=0;
	void show(){
		cout<<"CGirl::show():我是"<<m_bh<<"号,"<<m_age<<"岁。"<<endl; 
	}
};
int main(){
    CAllComers a; a.m_bh=3;//创建基类对象,并对成员赋值 
    CGirl g; g.m_bh=8;g.m_age=23;//创建派生对象,并对成员赋值 
    CAllComers* p;//声明基类指针 
    p=&a;p->show(); //让基类指针指向基类对象,并调用虚函数。 
	p=&g;p->show(); //让基类指针指向派生对象,并调用虚函数。 
;
	
	
	return 0;
}
CAllComers::show()我是3号。
CGirl::show():我是8号,23岁。

--------------------------------
Process exited after 0.5233 seconds with return value 0
请按任意键继续. . .

测试证明:有了虚函数,基类指针指向基类对象时就使用基类的成员函数和数据,指向派生类时就使用派生类的成员函数和数据。

基类指针表现出了多种类型,这种现象称之为多态

注意事项:

1.只需在基类的函数声明中加virtual关键字,函数定义时不能加。

#include<iostream>
using namespace std;
class CAllComers {
	public:
		int m_bh=0;
		virtual void show();
};
virtual void show() {
	cout<<"CAllComers::show()我是"<<m_bh<<"号。"<<endl;
}

这样会报错,函数定义的时候不可以加virtual关键字 ,应如下:

#include<iostream>
using namespace std;
class CAllComers {
	public:
		int m_bh=0;
		virtual void show();
};
void show() {
	cout<<"CAllComers::show()我是"<<m_bh<<"号。"<<endl;
}

2.在派生类中重新定义虚函数时,函数特征要相同;

#include<iostream>
using namespace std;
class CAllComers{
public:
	int m_bh=0;
	virtual void show(){
		cout<<"CAllComers::show()我是"<<m_bh<<"号。"<<endl; 
	} 

}; 
class CGirl:public CAllComers{
public:
	int m_age=0;
	void show(){
		cout<<"CGirl::show():我是"<<m_bh<<"号,"<<m_age<<"岁。"<<endl; 
	}
	void func(){
		cout<<"调用了func()函数\n";
	}
};
int main(){
    CAllComers a; a.m_bh=3;//创建基类对象,并对成员赋值 
    CGirl g; g.m_bh=8;g.m_age=23;//创建派生对象,并对成员赋值 
    CAllComers* p;//声明基类指针 
    //p=&a;p->show(); //让基类指针指向基类对象,并调用虚函数。 
	p=&g;p->show(); //让基类指针指向派生对象,并调用虚函数。 
    p->func();
	
	
	return 0;
}

报错:发现func()函数是派生类中新增的,基类指针找不到他。

如果给派生类的show()函数增加一个参数,编译运行没问题,但是日志显示的是基类的show()函数,不是派生类的。

class CGirl:public CAllComers{
public:
	int m_age=0;
	void show(int a){
		cout<<"CGirl::show():我是"<<m_bh<<"号,"<<m_age<<"岁。"<<endl; 
	}

};
CAllComers::show()我是8号。

--------------------------------
Process exited after 0.5254 seconds with return value 0
请按任意键继续. . .

 把派生类的show()函数里面的参数删掉,就正常调用派生类的show()函数了;

class CGirl:public CAllComers{
public:
	int m_age=0;
	void show(){
		cout<<"CGirl::show():我是"<<m_bh<<"号,"<<m_age<<"岁。"<<endl; 
	}

};
CAllComers::show()我是8号。

--------------------------------
Process exited after 0.5254 seconds with return value 0
请按任意键继续. . .

如果给派生类增加一个重载版本的show()函数,然后用基类指针调用重载版本的show()函数

#include<iostream>
using namespace std;
class CAllComers{
public:
	int m_bh=0;
	virtual void show(){
		cout<<"CAllComers::show()我是"<<m_bh<<"号。"<<endl; 
	} 

}; 
class CGirl:public CAllComers{
public:
	int m_age=0;
	void show(){
		cout<<"CGirl::show():我是"<<m_bh<<"号,"<<m_age<<"岁。"<<endl; 
	}
	void show(int a){
		cout<<"CGirl::show(int a):我是"<<m_bh<<"号,"<<m_age<<"岁。"<<endl; 
	}

};
int main(){
    CAllComers a; a.m_bh=3;//创建基类对象,并对成员赋值 
    CGirl g; g.m_bh=8;g.m_age=23;//创建派生对象,并对成员赋值 
    CAllComers* p;//声明基类指针 
    //p=&a;p->show(); //让基类指针指向基类对象,并调用虚函数。 
	p=&g;p->show(5); //让基类指针指向派生对象,并调用虚函数。 

	
	
	return 0;
}

也报错了;对基类指针来说,他不认识派生类中的重载函数,如果把基类的虚函数也增加这个重载版本,再编译就没问题了;

#include<iostream>
using namespace std;
class CAllComers{
public:
	int m_bh=0;
	virtual void show(){
		cout<<"CAllComers::show()我是"<<m_bh<<"号。"<<endl; 
	} 
	virtual	void show(int a){
		cout<<"CAllComers::show(int a)我是"<<m_bh<<"号。"<<endl;  
	}


}; 
class CGirl:public CAllComers{
public:
	int m_age=0;
	void show(){
		cout<<"CGirl::show():我是"<<m_bh<<"号,"<<m_age<<"岁。"<<endl; 
	}
	void show(int a){
		cout<<"CGirl::show(int a):我是"<<m_bh<<"号,"<<m_age<<"岁。"<<endl; 
	}

};
int main(){
    CAllComers a; a.m_bh=3;//创建基类对象,并对成员赋值 
    CGirl g; g.m_bh=8;g.m_age=23;//创建派生对象,并对成员赋值 
    CAllComers* p;//声明基类指针 
    //p=&a;p->show(); //让基类指针指向基类对象,并调用虚函数。 
	p=&g;p->show(5); //让基类指针指向派生对象,并调用虚函数。 

	
	
	return 0;
}
CGirl::show(int a):我是8号,23岁。

--------------------------------
Process exited after 0.5254 seconds with return value 0
请按任意键继续. . .

在派生类中重新定义虚函数时,函数特征要相同;

3.在派生类中重新定义了虚函数的情况下,如果想使用基类的虚函数,可以加类名和域解析符。

  • 6
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值