C++继承和派生

目录

一、继承方式与权限问题

1.继承的写法

2.继承的实质与权限问题

二、继承中的构造函数

三、继承中的同名问题

四、构造顺序问题

        1.单继承中的构造顺序问题

        2.多继承中的构造顺序问题


一、继承方式与权限问题

1.继承的写法

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

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

2.继承的实质与权限问题

                ● 继承的实质:父类的数据和成员子类中也有一份

#include<iostream>
#include<string>
using namespace std;
class Parent
{
public:
	void print()
	{
		cout << name << "\t" << money << endl;
	}
	string& getWife()
	{
		return wife;
	}
protected:
	int money;
	string name;
private:
	string wife;
};
class son :public Parent
{
public:
	void printSon()
	{
		print();
		cout << name <<"\t" << money << endl;
		//cout << wife << endl; -----父类中私有属性不能直接访问
		cout << getWife() << endl;	//间接通过父类的函数访问
	}
protected:
};
int main()
{
	son son1;
	son1.printSon();
	son1.print();
	while (1);
	return 0;
}

                ● 权限问题:继承方式只会增强父类属性在子类中的权限显示

publicprotectedprivate
protected继承protectedprotected不可直接访问
public继承publicprotected不可直接访问
private继承privateprivate不可直接访问
//父类
class A 
{
public:
	int a1;
protected:
	int a2;
private:
	int a3;
};
//public继承
class B :public A 
{
public:
	//int a1;
protected:
	//int a2;
private:
	//int a3;  不能直接访问
};
//protected继承
class C :protected A
{
public:
	
protected:
	//int a1;   //public 显示protected
	//int a2;
private:
	//int a3;  不能直接访问
};
//private继承
class D :private A
{
public:
	void print() 
	{
		cout << a1 << endl;
		cout << a2 << endl;
		//cout << a3 << endl;		//父类的私有属性不能直接访问
	}
protected:
	
private:
	//int a1;  
	//int a2;
	//int a3;   //父类的私有属性不能直接访问
};

//私有继承会导致当前父类 无法在孙子类有任何作用
class F :public D 
{
public:

};
int main()
{
	B b;
	b.a1 = 123;
	C c;
	//c.a1 = 12; -----在子类中变为protected无法类外访问
	while (1);
	return 0;
}

二、继承中的构造函数

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

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

        3.单继承和多继承的区别

                ● 单继承:只有一个父类

                ● 多继承:两个或两个以上的父类

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

#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 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;
}

三、继承中的同名问题

        1.数据成员同名

        2.成员函数名同名

        3.正常赋值调用

        4.非正常赋值调用

#include <iostream>
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<<"\t" << 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();

	//非正常的指针
	//1.允许子类对象初始化父类指针
	MM* pMM = new Girl("newGirl", 49);
	pMM->print();		//父类的
	//在没有virtual情况下,看指针类型
	//在有virtual情况,看赋值对象
	//2.父类对象初始化子类指针,不安全
	//Girl* pGirl = new MM("newMM", 29); 错误
	//Girl* pGirl = (Girl*)pM;
	//pGirl->print();  引发

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

四、构造顺序问题

        1.单继承中的构造顺序问题

                ● 先构造父类的在构造子类的,析构顺序相反

        2.多继承中的构造顺序问题

                ● 任何构造顺序问题都和初始化参数列表无关

                ● 构造顺序和继承顺序一致

#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、付费专栏及课程。

余额充值