C++继承和派生

C++继承和派生    

## 继承方式与权限问题

+ 继承的写法

```c++
//父类   基类
class parent
{
    
};
//子类   派生类
//公有继承
class son1:public parent
{
    public:
    protected:
};
//保护继承
class son2:protected parent
{
    public:
    protected:
};
//私有继承
class son3:private parent
{
    public:
    protected:
};
//继承和派生
//继承: 子类中没有产生新的属性或者行为
//派生: 派生类中有新的属性和行为产生
class 子类名:继承方式 父类名
{

    
};
//继承方式 就是权限限定词
```

+ 继承实质与权限问题
  + 继承的实质: 父类的数据和成员子类中有一份
  + 权限问题: 继承方式只会增强父类属性在子类中的权限显示

|                          | public          | protected | private           |
| -------------         | ---------         | --------   -  | ------------        |
| protected继承  | protected     | protected | 不可直接访问 |
| public继承       | public           | protected | 不可直接访问 |
| private继承      | private         | private     | 不可直接访问 |

继承中的构造函数

父类的属性通过父类的构造函数初始化

子类中的构造函数,必须要调用父类构造函数,必须采用初始化参数里列表的方式

单继承和多继承

单继承:只有一个父类

多继承:两个及两个以上的父类

继承的属性,无论被继承多少次都存在,所以类一般不会被继承很多层,会导致类的臃肿。  

#include <iostream>
#include <string>
using namespace std;
class Parent 
{
public:
	Parent() { cout << "父类无参构造函数" << endl; }
	Parent(string FName, string SName):FName(FName), SName(SName){}
protected:
	string FName;
	string SName;
};
//单继承
class Son :public Parent
{
public:
	//这种写法,父类必须存在无参的构造函数,当然缺省也可以
	Son() { cout << "子类无参构造函数" << endl; }    
	Son(string FName, string SName, string sonSName) :Parent(FName,SName)
	{
		//自己的属性用什么办法初始化都行
		this->sonFName = FName;
		this->sonSName = sonSName;
	}
	void print() 
	{
		cout << "父:" << FName + SName << endl;
		cout << "子:" << sonFName + sonSName << endl;
	}
protected:
	string sonFName;
	string sonSName;
	//string FName;
	//string SName;
};

//多继承
//欧田
//阳子
//欧阳 田子
class Mother
{
public:
	//Mother() = default;
	Mother(string mmFName, string mmSName)
	{
		this->mmFName = mmFName;
		this->mmSName = mmSName;
	}
protected:
	string mmFName;
	string mmSName;
};
class Father 
{
public:
	//Father() = default;
	Father(string ggFName, string ggSName)
	{
		this->ggFName = ggFName;
		this->ggSName = ggSName;
	}

protected:
	string ggFName;
	string ggSName;
};
class Baby :public Father,public Mother
{
public:
	//子类想要这种构造函数,每个父类都要有一个无参的构造函数
	//Girl() {}
	Baby(string mmFName, string mmSName, string ggFName, string ggSName)
		:Mother(mmFName,mmSName), Father(ggFName,ggSName)
	{
		/*
			//欧田
			//阳子
			//欧阳 田子
		*/
		girlFName = Father::ggFName + Mother::mmFName;  //欧阳
		girlSName = Father::ggSName + Mother::mmSName;  //田子
	}
	void print() 
	{
		cout << "父:" << ggFName + ggSName << endl;
		cout << "母:" << mmFName + mmSName << endl;
		cout << "女:" << girlFName + girlSName << endl;
	}
protected:
	string girlFName;
	string girlSName;
};
//继承的属性一致都存在
class A 
{
public:
	A(int a) :a(a) {}
	int a;
};

class B:public A
{
public:
	B(int a,int b) :A(a),b(b) {}
	int b;
};
class C :public B
{
public:
	C(int a, int b,int c) :B(a,b),c(c) {}
	int c;
};

class D :public C
{
public:
	D(int a, int b, int c,int d) :C(a,b,c), d(d) {}
	int d;
};

int main() 
{
	Son son;				//子类构造对象,优先调用父类构造函数
	Son son1("白", "老鬼", "日天");
	son1.print();
	Baby baby("阳", "子", "欧", "田");
	baby.print();
	return 0;
}

      构造函数中同名问题

数据成员同名

成员函数同名

#include<iostream>
using namespace std;
class Girl {
public:
	Girl(string name,int age):name(name),age(age){}
	//无论是成员函数还是数据成员不做特殊处理都是就近原则
	void print() {
		cout << "父类中的" << endl;
		cout << name << "\t" << age << endl;
	}
protected:
	string name;
	int age;
};

class Baby :public Girl {
public:
	Baby(string name,int age):Girl("父类",28),name(name),age(age){}
	void print() {
		cout << name << " " << age << endl;//同名时,不做特别处理,就近原则,调用子类的
		//远的用类名限定
		cout << Girl::name << " " << Girl::age << endl;
		//this指针标志的也是就近原则
	}
	
protected:
	string name;
	int age;
};

//虚继承(菱形继承)
class A {
public:
	A(int a) :a(a){}
protected:
	int a;
};
class B :virtual public A {
public:
	B(int a,int b):A(a),b(b){}
protected:
	int b;
};
class C :virtual public A {
public:
	C(int a, int c) :A(a), c(c){}
protected:
	int c;
};
class D :public B, public C {
public://菱形继承必须调用祖父的构造函数
	D() :B(1, 2), C(3, 4),A(999) {

	}
	void print() {
		//结果都一样,只有一份的含义
		cout << a << endl;
		cout << B::a << endl;
		cout << C::a << endl;
	}
protected:
};
int main() {
	//正常对象调用
	Baby baby("女孩", 18);
	baby.print();
	//正常指针调用
	Girl* pGirl = new Girl("newGirl", 19);
	pGirl->print();
	Baby* pBaby = new Baby("newBaby", 1);
	pBaby->print();
	pBaby->Girl::print();

	//非正常指针
	//允许子类对象初始化父类指针
	Girl* pMM = new Baby("newGirl",28);
	//调用父类的
	pMM->print();		//在没有virtual的情况下,看指针类型;在有virtual的情况下看赋值对象

	//父类对象初始化子类指针,不安全
	//Baby* pBB = new Girl("newBaby", 10);
	Baby* pBB = (Baby*)pMM;
	pBB->print();//只能调用父类当中子类有的函数//但一般不被允许

	D d;
	d.print();
	return 0;
}

构造和析构问题

单继承先构造父类的再构造子类的,析构顺序相反。

多继承

#include<iostream>
using namespace std;
class A {
public:
	A() { cout << "A"; }
	~A() { cout << "A"; }
protected:

};
class B :public A {
public:
	B() { cout << "B"; }
	~B() { cout << "B"; }
protected:

};
class C {
public:
	C() { cout << "C"; }
	~C() { cout << "C"; }
protected:

};
class D {
public:
	D() { cout << "D"; }
	~D() { cout << "D"; }
protected:

};
class E :public A, public C, public D {//构造顺序和初始化参数列表无关
//构造顺序和继承顺序一致ACDFFDA
public:
	E() { cout << "E"; }
	~E() { cout << "E"; }
};

int main() {
	B b;
	cout << endl;
	E f;


	return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值