c++多态之继承

c++之继承

为什么需要继承?

在这里插入图片描述
继承允许依据一个类来定义一个类,使得创建和维护一个应用程序更容易,提高效率。

#include<iostream>
using namespace std;

class IndexPage{
public:
	//网页头部
	void Header(){
		cout << "网页头部!" << endl;
	}
	//网页左侧菜单
	void LeftNavigation(){
		cout << "左侧导航菜单!" << endl;
	}
	//网页主体部分
	 void MainBody(){
		cout << "首页网页主题内容!" << endl;
	}
	//网页底部
	void Footer(){
		cout << "网页底部!" << endl;
	}
private:
	string mTitle; //网页标题
};

//如果不使用继承,那么定义新闻页类,需要重新写一遍已经有的代码
//class NewsPage{
//public:
//	//网页头部
//	void Header(){
//		cout << "网页头部!" << endl;
//	}
//	//网页左侧菜单
//	void LeftNavigation(){
//		cout << "左侧导航菜单!" << endl;
//	}
//	//网页主体部分
//	void MainBody(){
//		cout << "新闻网页主体内容!" << endl;
//	}
//	//网页底部
//	void Footer(){
//		cout << "网页底部!" << endl;
//	}
//	private:
//	string mTitle; //网页标题
//};

//使用继承,可复用已有的代码

class NewsPage:public IndexPage
{
	public:
	void MainBody()
	{
		cout << "新闻网页主体 "<<endl;
	}	
}; 

int main()
{
	NewsPage p;
	p.Footer();
	p.MainBody();
	return 0;
 } 

派生类定义:
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

//基类
class A{
public:
	int mA;
protected:
	int mB;
private:
	int mC;
};

//1. 公有(public)继承
class B : public A{
public:
	void PrintB(){
		cout << mA << endl; //可访问基类public属性
		cout << mB << endl; //可访问基类protected属性
		//cout << mC << endl; //不可访问基类private属性
	}
};
class SubB : public B{
	void PrintSubB(){
		cout << mA << endl; //可访问基类public属性
		cout << mB << endl; //可访问基类protected属性
		//cout << mC << endl; //不可访问基类private属性
	}
};
void test01(){

	B b;
	cout << b.mA << endl; //可访问基类public属性
	//cout << b.mB << endl; //不可访问基类protected属性
	//cout << b.mC << endl; //不可访问基类private属性
}

//2. 私有(private)继承
class C : private A{
public:
	void PrintC(){
		cout << mA << endl; //可访问基类public属性
		cout << mB << endl; //可访问基类protected属性
		//cout << mC << endl; //不可访问基类private属性
	}
};
class SubC : public C{
	void PrintSubC(){
		//cout << mA << endl; //不可访问基类public属性
		//cout << mB << endl; //不可访问基类protected属性
		//cout << mC << endl; //不可访问基类private属性
	}
};
void test02(){
	C c;
	//cout << c.mA << endl; //不可访问基类public属性
	//cout << c.mB << endl; //不可访问基类protected属性
	//cout << c.mC << endl; //不可访问基类private属性
}
//3. 保护(protected)继承
class D : protected A{
public:
	void PrintD(){
		cout << mA << endl; //可访问基类public属性
		cout << mB << endl; //可访问基类protected属性
		//cout << mC << endl; //不可访问基类private属性
	}
};
class SubD : public D{
	void PrintD(){
		cout << mA << endl; //可访问基类public属性
		cout << mB << endl; //可访问基类protected属性
		//cout << mC << endl; //不可访问基类private属性
	}
};
void test03(){
	D d;
	//cout << d.mA << endl; //不可访问基类public属性
	//cout << d.mB << endl; //不可访问基类protected属性
	//cout << d.mC << endl; //不可访问基类private属性
}

在继承过程中如果遇到同名成员函数的话该怎么办?
1、当子类成员和父类成员同名时,子类依然从父类继承同名成员。
2、如果子类有成员和父类同名,子类访问其成员默认访问子类的成员(就近原则)。
3、子类通过作用域::进行同名成员的区分。

#include<iostream>
using namespace std;

class Base{
public:
	Base():mParam(0){}
	void Print(){ cout << mParam << endl; }
public:
	int mParam;
};

class Derived : public Base{
public:
	Derived():mParam(10){}
	void Print(){
		//在派生类中使用和基类的同名成员,显示使用类名限定符
		cout << Base::mParam << endl;
		cout << mParam << endl;
	}
	//返回基类重名成员
	int& getBaseParam(){ return  Base::mParam; }
public:
	int mParam;
};

int main(){

	Derived derived;
	//派生类和基类成员属性重名,子类访问成员默认是子类成员
	cout << derived.mParam << endl; //10
	derived.Print();
	//类外如何获得基类重名成员属性
	derived.getBaseParam() = 100;
	cout << "Base:mParam:" << derived.getBaseParam() << endl;

	return 0;
}

如果重新定义基类中的重载函数,会发生什么?

class Base{
public:
	void func1(){
		cout << "Base::void func1()" << endl;
	};
	void func1(int param){
		cout << "Base::void func1(int param)" << endl;
	}
	void myfunc(){
		cout << "Base::void myfunc()" << endl;
	}
};
class Derived1 : public Base{
public:
	void myfunc(){
		cout << "Derived1::void myfunc()" << endl;
	}
};
class Derived2 : public Base{
public:
	//改变成员函数的参数列表
	void func1(int param1, int param2){
		cout << "Derived2::void func1(int param1,int param2)" << endl;
	};
};
class Derived3 : public Base{
public:
	//改变成员函数的返回值
	int func1(int param){
		cout << "Derived3::int func1(int param)" << endl;
		return 0;
	}
};
int main(){

	Derived1 derived1;
	derived1.func1();
	derived1.func1(20);
	derived1.myfunc();
	cout << "-------------" << endl;
	Derived2 derived2;
	//derived2.func1();  //func1被隐藏
	//derived2.func1(20); //func2被隐藏
	derived2.func1(10,20); //重载func1之后,基类的函数被隐藏
	derived2.myfunc();
	cout << "-------------" << endl;
	Derived3 derived3;
	//derived3.func1();  没有重新定义的重载版本被隐藏
	derived3.func1(20);
	derived3.myfunc();

	return 0;
}

任何时候重新定义基类中的一个重载函数,在新类中所有的其他版本将被自动隐藏.

虚继承(解决二义性问题)

在这里插入图片描述

class BigBase{
public:
	BigBase(){ mParam = 0; }
	void func(){ cout << "BigBase::func" << endl; }
public:
	int mParam;
};

class Base1 : public BigBase{};
class Base2 : public BigBase{};
class Derived : public Base1, public Base2{};

int main(){

	Derived derived;
	//1. 对“func”的访问不明确
	//derived.func();
	//cout << derived.mParam << endl;
	cout << "derived.Base1::mParam:" << derived.Base1::mParam << endl;
	cout << "derived.Base2::mParam:" << derived.Base2::mParam << endl;

	//2. 重复继承
	cout << "Derived size:" << sizeof(Derived) << endl; //8

	return 0;
}

采用虚基类

class BigBase{
public:
	BigBase(){ mParam = 0; }
	void func(){ cout << "BigBase::func" << endl; }
public:
	int mParam;
};

class Base1 : virtual public BigBase{};
class Base2 : virtual public BigBase{};
class Derived : public Base1, public Base2{};

int main(){

	Derived derived;
	//二义性问题解决
	derived.func();
	cout << derived.mParam << endl;
	//输出结果:24
	cout << "Derived size:" << sizeof(Derived) << endl;

	return 0;
}

虚继承中增加了一个虚指针。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值