C++ (类继承,虚基类,多重继承)

类继承

类继承这种方式使我们的代码更为简洁和高效


先回顾一下三种访问控制关键字

  • public: public所修饰的成员变量可以在类内(包括子类)和类外进行访问。
  • protected: protected所修饰的成员变量只能在类内(包括子类)进行访问。
  • private: private所修饰的成员变量只能在类内访问(不包括子类)。


继承的方式

  • 公有继承
class 派生类(子类)名 :public  基类(父类)名{

	派生类(子类)新增成员;

};

公有继承对基类成员访问权限的控制:

基类成员派生类成员
public成员public成员
protected成员protected成员
private成员不可访问成员
不可访问成员不可访问成员

  • 私有继承
class 派生类(子类)名  : private 基类(父类)名{

	派生类(子类)新增成员;

};

私有继承对基类成员访问权限的控制:

基类成员派生类成员
public成员private成员
protected成员private成员
private成员不可访问成员
不可访问成员不可访问成员

  • 保护继承
class 派生类(子类)名  : protected  基类(父类)名{

	派生类(子类)新增成员;

};

保护继承对基类成员访问权限的控制:

基类成员派生类成员
public成员protected成员
protected成员protected成员
private成员不可访问成员
不可访问成员不可访问成员


类继承中的一些细节

  • 派生类(子类)构造函数传参的时候会包含基类的成员和派生类的成员
  • 并且基类的成员一定要使用初始化表的形式进行初始化,子类成员没有要求。
    如:
class A{

private:
	int x,y;
public:
	A(int ax,int ay){
		x = ax;
		y = ay;
	}
};

class B : public A{

private:
	int z;
public:
	B(int bx,int by,int bz):A(bx,by),z(bz){}
	
};
  • 如果基类中有带参数的构造函数,即使派生类中不需要初始化新的数据成员,派生类中也必须定义构造函数。
  • 如果基类中定义了多个构造函数,那么派生类中也要相应地定义多个构造函数。
    如下:
基类:
class Student{
public:
	Student(const string& name):strName(name),cSex('M'),nAge(18){}
	Student(const string& name,char sex):strName(name),cSex(sex),nAge(18){}
	Student(const string& name,char sex,int age):strName(name),cSex(sex),nAge(age){}
private:
	string strName;
	char cSex;
	int nAge;
};

派生类:

class Athlete : public Student {
public:
	Athlete(const string& name):Student(name){}
	Athlete(const string& name,char sex):Student(name,sex){}
	Athlete(const string& name,char sex,int age):Student(name,sex,age){}
	void ShowInfo(){cout<<"Hello"<<endl;}
};

可见,在派生类中也有和基类相对应的构造函数,但是,派生类中并没有新增的数据成员!!这样看来,派生类中的构造函数是不是很复杂?

所以,在C++11中,提供了继承基类构造函数的方法,使得派生类中可以直接使用基类的构造函数。(不经常使用,了解即可)
在这种方法中,只需要在派生类中用using进行声明,把基类的构造函数声明到派生类里面即可:
修改派生类Athlete

class Athlete : public Student {
public:
	using Student::Student;
	void ShowInfo(){cout<<"Hello"<<endl;}
};
       using Student::Student这句可以理解为引入了Student类中的Student函数。

但是,如果派生类中有新增的数据成员,并且需要初始化,那么就必须给派生类定义构造函数,并且显式调用基类的构造函数,初始化基类数据成员。



派生类的析构函数

  • 当回收派生类对象新增成员所占用的内存空间时,必须为派生类定义析构函数,如指针 就需要用到析构函数。

创建派生类对象时先调用基类的构造函数,后调用派生类的构造函数。
当派生类对象生命期结束时,先调用派生类的析构函数,后调用基类的析构函数。



隐藏基类成员

  • 在派生类中重新定义定义与基类同名成员的时候,派生类中的成员隐藏基类的同名成员,派生类中对这些同名成员赋予了新的意义和功能
  • 如果我们要调用基类中的函数而不是使用派生类中的同名函数的时候,就要写成下面这种形式:
    下面例子中,派生类中Test函数将基类中的Test函数隐藏。
class Student{
public:
	void Test(int);//基类中有一个Test,里面参数是int类型
};

class Doctor : public Student{
public:
	void Test();//派生类中也有一个Test函数,但没有参数。
};

int main(){
	Doctor d;//创建一个Doctor类的成员,这里没有写构造函数。
	d.Test();//调用派生类中的Test函数
	
	这里派生类中的Test把基类中的Test隐藏,要通过下面这种方法调用!
	不能理解为函数重载,不一样!!!!
	
	d.Student::Test(3);//调用基类中的Test函数
};


多重继承

如果派生类有两个或多个直接基类,这种继承就成为多重继承(多继承)。

class 派生类名: 继承方式 基类1,继承方式 基类2.... 继承方式 基类 n{
	派生类新增成员;
};

其中,数据成员的排列规则要按照派生类定义中基类的顺序将基类成员依次排列,然后存放派生类中的新增成员,这里成员的存储位置相邻。



多重继承引起的二义性

有两种方式消除二义性:

  1. 用更多的属性区别他们。可以用类名和域运算符“::”进行限定
cout<< B::x <<endl;
  1. 在派生类成员中改写有歧义的同名成员
class A{
protected:
	int x;
public:
	A(int x);
};
class B{
protected:
	int x;
public:
	B(int x);
};

class C : public A, public B{
protected:
	int x;
public:
	void showInfo(){
		cout<<x<<endl;//这里的x容易产生二义性,所以我们在类C中定义了新的int类型的 x;
	}
};


虚基类

在派生类中保留了间接共同基类的多份同名成员,会占用较多存储空间,增加访问难度,容易出现二义性错误,对此,C++提供了虚基类的方法,使得派生类在继承间接共同基类的时候只保留一份成员

什么是间接共同基类呢?

举个例子:
B、C都继承了A,D继承了B和C,那么A就是D的间接共同基类。

**虚基类的定义格式 **

class 派生类名 : virtual  继承方式  基类名{

	派生类新增成员;
	
};

那么,继上面的例子 ,虚基类定义在类B 和 类C上即可,类D上写不写都可以。

注意:最后定义的派生类,即类的层次结构中最底层的派生类完成虚基类构造函数的调用,该派生类的其他基类对虚基类的构造函数的调用将被忽略。

Over

GL&HF

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C++工资管理系统多继承、虚函数、虚基类的实现方法如下: 1. 多继承继承是指一个可以从多个基类继承属性和方法。在C++中,可以通过在定义中使用逗号分隔多个基类来实现多继承。例如: ```cpp class Base1 { public: void func1(); }; class Base2 { public: void func2(); }; class Derived : public Base1, public Base2 { public: void func3(); }; ``` 在上面的例子中,Derived从Base1和Base2两个基类继承了属性和方法。 2. 虚函数 虚函数是指在基类中声明的函数,在派生中可以被重写。在C++中,可以通过在函数声明前加上virtual关键字来声明虚函数。例如: ```cpp class Base { public: virtual void func(); }; class Derived : public Base { public: void func(); // 重写了Base中的虚函数 }; ``` 在上面的例子中,Base中的func()函数是虚函数,Derived中的func()函数重写了Base中的虚函数。 3. 虚基类 虚基类是指在多重继承中,为了避免派生中出现多个基类的副本,而将某个基类设置为虚基类。在C++中,可以通过在基类名前加上virtual关键字来声明虚基类。例如: ```cpp class Base { public: int num; }; class Base1 : virtual public Base { public: void func1(); }; class Base2 : virtual public Base { public: void func2(); }; class Derived : public Base1, public Base2 { public: void func3(); }; ``` 在上面的例子中,Base被声明为虚基类,Derived中只包含一个Base的副本。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值