返回顶部

C++继承

继承就是类之间的一种关系,子类拥有父类的一切,也能够完成父类的所有可以完成的事务。父类也即基类,子类也即派生类。(子类和基类是相对而言的)。

继承的方式一般写成:

class 子类:继承权限 父类,…,继承权限 父类

因为C++支持多继承,所以继承列表可以有多个父类,以逗号分隔。

继承权限

继承关键字

C++提供三个权限关键字:publicprotectedprivate。(一般使用第一种。)

  • 公有继承(public):当一个类派生自公有基类时,基类的公有成员也是派生类的公有成员,基类的保护成员也是派生类的保护成员,基类的私有成员不能直接被派生类访问,但是可以通过调用基类的公有和保护成员来访问。
  • 保护继承(protected):当一个类派生自保护基类时,基类的公有和保护成员将成为派生类的保护成员。
  • 私有继承(private):当一个类派生自私有基类时,基类的公有和保护成员将成为派生类的私有成员。

访问控制

继承权限 public protected private
public public protected private
protected protected protected private
private private private private
访问 public protected private
同一个类
派生类 ×
外部的类或函数 × ×

一个派生类继承了所有的基类方法,以下情况除外:

  • 基类的构造函数、析构函数和拷贝构造函数
  • 基类的重载运算符
  • 基类的友元函数

示例:

//基类
class Shape {
protected:
	int x, y;
public:
	Shape(int x, int y) {
		this->x = x;
		this->y = y;
	}
};
//基类
class volume {
protected:
	int calVolume(int x, int y, int z) {
		return x * y * z;
	}
};
//派生类
class Cube:public Shape , public volume {
private:
	int z;
public :
	Cube(int x, int y, int z):Shape(x , y){
		this->z = z;
	}
	int cal() {
		return calVolume(x, y, z);
	}
};
int main() {
	Cube cube(1, 2, 3);
	cout << "立方体的体积为:" << cube.cal() << endl;
	return 0;
}

输出:立方体的体积为:6

继承的构造与析构

在生成子类对象过程中会首先调用父类构造函数,然后再调用子类构造函数,这样就让父类构造函数把父类部分数据初始化了一遍,然后通过调用子类构造函数初始化子类成员。而对于析构函数就刚好相反了,秉承着先进后出的堆栈思想。

有如下示例:

class A {
public:
	A() {cout << "A" << endl;}
	~A() { cout << "DA" << endl; }
};
class B {
public:
	B() { cout << "B" << endl; }
	~B() { cout << "DB" << endl; }
};
class C :public A, public B {
public:
	C() { cout << "C" << endl; }
	~C() { cout << "DC" << endl; }
};

int main() {
	C* c = new C();
	delete c;
	return 0;
}

输出:类名表示调用了构造函数,在类名前加D表示调用了析构函数

A
B
C
DC
DB
DA

因为在C++中存在多继承,对于上述程序,若B也继承于A,则输出为:

A
A
B
C
DC
DB
DA
DA

发现对象A被构造了两次,为了解决这一问题,可以在继承关键字前加上virtual关键字,即:

class A {
public:
	A() {cout << "A" << endl;}
	~A() { cout << "DA" << endl; }
};
class B:virtual public A {
public:
	B() { cout << "B" << endl; }
	~B() { cout << "DB" << endl; }
};
class C :virtual public A, public B {
public:
	C() { cout << "C" << endl; }
	~C() { cout << "DC" << endl; }
};

int main() {
	C* c = new C();
	delete c;
	return 0;
}

输出:

A
B
C
DC
DB
DA

对于上述代码,若删去CB继承的virtual关键字都会导致编译失败(VS2022)。

上述添加virtual关键字的继承方式称为虚继承,虚继承在创建父类对象的时候会创建一个虚表。

改变访问权限

使用 using 关键字可以改变基类成员在派生类中的访问权限,例如将 public 改为 private、将 protected 改为 public

注意:using 只能改变基类中 publicprotected 成员的访问权限,不能改变 private 成员的访问权限,因为基类中 private 成员在派生类中是不可见的,根本不能使用,所以基类中的 private 成员在派生类中无论如何都不能访问。

实例:

class A {
public:
	A(){}
	~A(){}
	void func() {};
protected:
	int a, b, c;
};
class B : public A {
public:
	B(){}
	~B(){}
	using A::a;//将protected改为public
	using A::b;
	int d;
private:
	using A::func;//将public 改为 private
};

参考资料

C++ 继承

C++三种继承方式

posted @ 2022-01-22 17:07  cherish-lgb  阅读(62)  评论(0编辑  收藏  举报