【第8节 C++继承和派生】

第8节 C++继承和派生

继承方式与权限问题

继承的写法

//父类 基类
class parent
{

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

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

继承实质与权限问题

  • ​ 继承的实质:父类的数据和成员子类中有一份
  • ​ 权限问题:继承方式只会增强父类属性在子类中的权限显示
publicprotectedprivate
public继承publicprotected不可直接访问
protected继承protectedprotected不可直接访问
private继承privateprotected不可直接访问
#include<iostream>
#include<string>
using namespace std;
class parent
{
public:
	void print()
	{
		cout << name << "\t" << money << endl;
	}
	string& getWide()
	{
		return wide;
	}
protected:
	string name;
	int money;
private:
	string wife;
};
//子类
class son :public parent
{
public:
	void printSon()
	{
		print();
		cout << name<<"\t"<<money<< endl;
		//cout << wife << endl;父类中的私有属性不能直接访问
		cout << getWide() <<endl;//间接通过父类的函数访问
	}
protected:

};
class A
{
public:
	int a1;
protected:
	int a2;
private:
	int a3;
};
class B :public A
{
public:
	//int a1;   
protected:

	//int a2;
private:
	//int a3;不能直接访问
};
class C :protected A
{
public:

protected:
	//int a1;   public 显示protected
	//int a2;
private:
	//int a3;不能直接访问
};
class D :private A
{
public:
	void print()
	{
		cout << a1 << endl;;
		cout << a2<< endl;
	}

protected:

private:
   //int a1;   public 显示protected
	//int a2;
	//int a3;//父类的私有属性不能直接访问
};

//私有继承会导致当前父类 无法在孙子类有任何作用
class F :public D
{
public:
};
int main()
{
	son boy;
	boy.printSon();
	 
	B b;
	b.a1 = 123;
	C c;
	//c.a1 = 12;
	return 0;
}

继承中的构造函数

  • 父类的属性通过父类的构造函数初始化
  • 子类中的构造函数,必须要调用父类构造函数,必须采用初始化参数列表的方式
#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 = sonFName;
		this->sonSName = sonFName;
	}
	void print()
	{
		cout << "父:" << FName + SName << endl;
		cout << "子:" << sonFName + sonSName << endl;;
	}
protected:
	string sonFName;
	string sonSName;
	//string FName;
	//string SName;
};

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

}

单继承和多继承

  • ​ 单继承:只有一个父类
  • ​ 多继承:两个或者两个以上的父类、
  • ​ 继承的属性一直都存在,无论被继承多少次,所以类一般不会被继承很多层,会导致类的臃肿
#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 = sonFName;
		this->sonSName = sonFName;
	}
	void print()
	{
		cout << "父:" << FName + SName << endl;
		cout << "子:" << sonFName + sonSName << endl;;
	}
protected:
	string sonFName;
	string sonSName;
	//string FName;
	//string SName;
};
//多继承
//欧田
//阳子
//欧阳田子

class MM
{
public:
	//MM() = default;
	MM(string mmFName, string mmSName)
	{
		this->mmFName = mmFName;
		this->mmSName = mmSName;
	}
protected:
	string mmFName;
	string mmSName;
};
class GG
{
public:
	//GG() = default;
	GG(string ggFName, string ggSName)
	{
		this->ggFName = ggFName;
		this->ggSName = ggSName;
	}
protected:
	string ggFName;
	string ggSName;
};
class Girl:public GG,public MM
{
public:
	//子类想要这种构造函数,每个父类都要有一个无参的构造函数
	//Girl(){}
	Girl(string mmFName, string mmSName, string ggFName, string ggSName)
		:MM(mmFName, mmSName), GG(ggFName,ggSName)
	{
		girlFName = ggFName + mmFName;
		girlSName = ggSName + 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();
	Girl girl("阳", "子", "欧","田");
	girl.print();
	return 0;

}

继承中同名问题

  • 数据成员同名
  • 成员函数同名
  • 正常调用
  • 非正常赋值调用
#include <iostream>
#include<string>
using namespace std;
class MM
{
public:
	MM(string name, int age) :name(name), age(age){}
	void print()
	{
		cout << "MM:";
		cout << name << "\t" << age << endl;
	}
protected:
	string name;
	int age;
};
class Girl :public MM
{
public:
	Girl(string name, int age) :MM("父类", 28), name(name), age(age){}
	void print()
	{
		//不做特别处理,就近原则
		cout << name << "" << age << endl;
		//类名限定
		cout << MM::name << "\t" << MM::age << endl;
		MM::print();
	}
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){}
	void printC()
	{
		cout << a << endl;
	}
protected:
	int c;
};
class D :public C, public B
{
public:
	//菱形继承,必须调用祖父的构造函数
	D() :B(1, 2), C(3, 4),A(999)
	{

	}
	void print()
	{
		//只有一个a 只有一份
		cout << a << endl;
		cout << B::a << endl;
		cout << C::a << endl;
		printC();
	}
protected:
};



int main()
{
	//不做特别处理,就近原则
	//正常对象调用
	Girl girl("girl", 18);
	girl.print();
	MM mm("mm", 28);
	mm.print();
	//正常的指针调用
	//就近原则
	Girl* pG = new Girl("newGirl", 19);
	pG->print();
	pG->MM::print();
	MM* pM = new MM("newMM", 29);
	pM->print();

	//非正常的指针
	//允许子类对象初始化父类指针
	MM* pMM = new Girl("newGilr", 49);
	pMM->print();//父类的
	//在没有virtual 情况下,看指针类型
	//在有virtual情况,看赋值对象
	//父类对象初始化子类指针,不安全
	//Girl *pGirl = new MM("newMM",29);错误
	//Girl* pGirl = (Girl*)pM;
	//pGirl->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"; }
    };
    
    class C
    {
    public:
    	C(){ cout << "C"; }
    	~C(){
    		cout << "C";
    	}
    };
    class D
    {
    public:
    	D(){ cout << "D"; }
    	~D(){
    		cout << "D";
    	}
    };
    //构造顺序和继承顺序一致
    class F :public C, public A, public D
    {
    public:
    	//任何构造顺序问题,都和初始化参数列表无关
    	F(){ cout << "F"; }
    	~F(){ cout << "F"; }
    };
    //CADF FDAC
    int main()
    {
    	{ 
    		B b;//ABBA
    	}
    
    	cout << endl;
    	F f;
    	return 0;
    }
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值