C++中的继承和派生

1.继承方式与权限问题

   继承的实质与权限:

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

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

publicprotectedprivate
protected继承protectedprotected不可直接访问
public继承publicprotected不可直接访问
private继承privateprivate不可直接访问
#include <iostream>
using namespace std;

//继承的3种写法
//父类   基类
class parent
{
public:
	void printdata()
	{
		cout << name << endl << age;
	}
protected:
	string name;
	int age;
private:
	int A;
};
//子类  派生类
//公有继承
class son1 :public parent
{
public:
	void printson1()
	{
		printdata();
		cout << name << endl << age;
	//	cout << A << endl;//父类中的私有属性不能直接访问,可间接访问
	}//继承:父类中的属性在子类中也有一份
protected:
private:
	
};
//保护继承
class son2 :protected parent//最低权限为保护权限,父类中的public转换为子类中的protected:
{
public:
protected:
private:
};
//私有继承
class son3 :private parent//最低权限为保护权限,父类中的public,protected转换为子类中的private:
{
public:
	void print()
	{
		cout << name << age;
	}
protected:
private:
};//私有继承会导致当前父类 无法在孙子类有任何作用
//class子类名:继承方式 父类名
//继承:子类中没有产生新的属性和行为
//派生:派生类中有新的属性和行为产生
int main()
{
	son1 son1;
	son1.printdata();
	son2 son2;
	//son2.printdata();不可访问,已转换为protected
	son3 son3;
	son3.print();
	return 0;
}

2.继承中的构造函数

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

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

单继承:只有一个父类    多继承:两个及两个以上的父类

继承的属性,类一般不会被继承很多层

class Parent
{
public:
	Parent()
	{
		cout << "父类无参构造函数";
	}
	Parent(string Fname, string Sname) :Fname(Fname), Sname(Sname) {}
protected:
	string Fname:
	string Sname;
};
class Son1 :public Parent
{
public:
	Son1() {} //这种写法,父类中必须存在一个无参的构造函数
	Son1(string Fname, string Sname, string Ssname):Parent(Fname,Sname)
	{
		this->Sfname = Fname;
		this->Ssname = Ssname;
	}
protected:
	string Sfname;
	string Ssname;
};

class A
{
public:
	A() = default;
	A(int A) :a(A)
	{
		this->a = A;
	}
protected:
	int a;
};
class B
{
public:
	B() = default;
	B(int B) :b(B)
	{
		this->b = B;
	}
protected:
	int b;
};

class AB:public A,public B
{
public://AB(){}子类想要这种构造函数,每个父类都要有一个无参的构造函数
	AB() {}
	AB(int ab) :ab(ab)
	{
		this->ab = ab;
	}
protected:
	int ab;
};

int main()
{
	Son1 son1;//子类构造对象,优先调用父类构造函数
	Son1 A("sjkd", "oshd", "skhpd");
	AB AB(8);
	return 0;
}

3.继承中的同名问题

数据成员同名

成员函数同名

正常赋值同名

class A
{
public:
	A(string name, int age) :name(name), age(age) {}
	void print()
	{
		cout << name << endl << age;
	}
protected:
	string name;
	int age;
};
class B:public A
{
public:
	B(string name, int age) :A("父类",18),name(name), age(age) {}
	void print()
	{//就近原则
		cout << name << endl << age;
		cout << A::name << endl << A::age;
	}
protected:
	string name;
	int age;
};
//虚继承  菱形继承
class AA
{
public:
	AA() = default;
	AA(int a) :a(a) {}
protected:
	int a;
};
class BB:virtual public AA
{
public:
	BB(int a, int b) :AA(a), b(a) {}
protected:
	int b;
};
class CC :virtual public AA
{
public:
	CC(int a, int c) :AA(a), c(c) {}
protected:
	int c;
};
class DD :public BB, public CC
{
public://菱形继承,必须调用祖父的构造函数
    DD() :BB(1, 2), CC(3, 4) {}
protected:

};
int main()
{
	B b("lskfn", 18);
	b.print();
	//正常的指针调用
	B* pB = new B("kjsbd", 18);
	pB->print();
	A* pA = new A("lknfsl", 18);
	pA->print();
	//非正常
	//允许子类对象初始化父类指针
	A* PA = new B("lksfn", 20);
	PA->print();//父类
	//在没有virtual情况下 看指针类型
	//在有virtual情况下  看赋值对象
	//父类对象初始化子类指针,不安全,不要这样操作
	return 0;
}

4.构造顺序问题

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

多继承:任何构造顺序问题都和初始化参数列表无关

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

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

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

};
class D
{
public:
	D() { cout << "D"; }
	~D() { cout << "D"; }
};
class E :public C, public A, public D
{
public:
	E() { cout << "E"; }
	~E() { cout << "E"; }
};

int main()
{
	//B B;//输出ABBA
	E E;//输出CADFFDAC
	return 0;
}

HOMEWORK:

#define PI 3.14

class Shape
{
public:
	int width = 10;
	int heigth = 10;
	int radius = 10;
};
class Rect:public Shape
{
public:
	void RprintS()
	{
		cout << "矩形的面积是" << width * heigth << endl;
	}
	void RprintC()
	{
		cout << "矩形的周长是" << (width + heigth) * 2 << endl;
	}
protected:
};
class Circle :public Shape
{
public:
	void CprintS()
	{
		cout << "圆形的面积是" << PI*radius*radius << endl;
	}
	void CprintC()
	{
		cout << "圆形的周长是" << 2*PI*radius << endl;
	}
protected:
};

int main()
{
	Rect R;
	R.RprintC();
	R.RprintS();
	Circle C;
	C.CprintC();
	C.CprintS();
	return 0;
}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值