在友元类中我们知道,一旦在一个类中声明了友元类,那么友元类便拥有了访问该类的所有权限,可以在自己的类中对声明自己的类进行一系列操作。

友元类主要目的是为了拓展友元类的功能,但是友元类的权限未免太多了,有什么办法可以削减其访问权限呢?

继承与派生应运而生;

本篇文章主要介绍如下内容:

1> 公有继承(public)

2> 私有继承(private)

3> 保护继承(protected)

4> 三种继承方式的共同点与差异

5> 派生类的构造函数

6> 多层派生 (存储地址)

7> 多继承

8> 多继承时派生类的构造函数

****************************************************************************************************************************************

 

一:公有继承

1> 公有继承特点:

 ☆ C++ 继承与派生

2> 公有继承示例 (这里的构造函数将在第五点讲到)

class Person{
private:
	int age;
	string name;
	string sex;
public:
	Person(int a, string b, string c)
	{
		age = a; name = b; sex = c;
	}
	void Print1();
};
void Person::Print1()
{
	cout << name << " " << sex << " " << age << endl;
}

class Student2:public Person{
private:

public:
	Student2(int a, string b, string c) :Person(a, b, c) {

	}
	void Print();
};
void Student2::Print(){
	cout << "Student2:";
	Person::Print1();
}

int main()
{
	Student2 S2(25,"Student2","Male");
	S2.Print();
	S2.Print1();
	return 0;
}

这里派生类的对象是可以直接访问基类public成员函数的,但是私有继承则不允许访问:

☆ C++ 继承与派生

 

 

二:私有继承

1> 私有继承特点

☆ C++ 继承与派生

2> 私有继承举例 (将上面的继承方式改为private)

☆ C++ 继承与派生

这里我们就可以直接看到私有继承的第三条特点:

一旦继承方式由公有变为私有,使用类的对象访问基类的权限已经被完全抹杀了,本来公有继承还可以访问public数据成员的~

 

 

三:保护继承

1> 保护继承特点

☆ C++ 继承与派生

2> 保护继承举例

除了第一条不私有继承不同外,其他都是相同的。

 

 

四:三种继承方式的共同点与差异

1> 三种继承方式的第一个特点都是控制基类被继承后的属性,

     这样做是为了当继承类再被继承后明确各个继承类与基类之间的关系

☆ C++ 继承与派生

2> 第二条特点三者是一致的,规定了在派生类中对基类中各部分的访问权限。

     而第三条特点则是对在派生类的外部,通过对象对基类进行操作权限进行了限制。

 

 

五:派生类的构造函数

☆ C++ 继承与派生

1> 基类的构造函数不会被派生类继承,但是当派生类中没有对基类的函数进行初始化的时候,会自动调用基类中的构造函数进行初始化;

2> 当继承类基类中都没有构造函数,一律使用系统默认的构造函数;

3> 如第一点所说,这时就要在派生类中使用指定的格式调用基类构造函数进行初始化。

在开篇的公有继承示例中:

class Person{
private:
    int age;
    string name;
    string sex;
public:
    Person(int a, string b, string c)
    {
        age = a; name = b; sex = c;
    }
    void Print1();
};
void Person::Print1()
{
    cout << name << " " << sex << " " << age << endl;
}

class Student2:public Person{
private:
    int pocket_month;
public:
    Student2(int a, string b, string c,int d) :Person(a, b, c) {
    pocket_month = d;
    }
    void Print();
};
void Student2::Print(){
    cout << "Student2:";
    Person::Print1();
}

我们可以发现Person基类中有相应的构造函数,当被继承的时候,我们就要考虑如何对基类数据进行初始化,那如何对基类中的数据进行初始化呢?

这里额外提一点,那到底为什么要初始化基类数据呢

回到本质,继承与派生的最初目的是为了减少代码的重用,即当两个类A、B中有大量一致的成员,可以将一致的成员提取出来,独自封装为一个类C,然后再通过继承来使用这个重复的类C,

然后分别在A、B类中给C中的数据赋予不同的数据进而完善A、B类,这样做就使得这些重复的部分在系统内存中只有一个备份,从而减少了资源开销,而且A、B类所需求的数据没有改变。

 

派生类中构造函数格式:

☆ C++ 继承与派生

 构造函数中的部分称呼:

☆ C++ 继承与派生

 

 

六:多层派生 (派生类继续作为基类派生)

1> 示例:

#include <iostream>
using namespace std;

class B0	//基类B0声明
{
public:
	void display() { cout << "B0::display()" << endl; }	//公有成员函数
};
class B1 : public B0
{
public:
	void display() { cout << "B1::display()" << endl; }
};
class D1 : public B1
{
public:
	void display() { cout << "D1::display()" << endl; }
};

void fun(B0 *ptr) 
{
	ptr->display();
} 	//"对象指针->成员名"

void main()	//主函数
{
	B0 b0;	//声明B0类对象
	B1 b1;	//声明B1类对象
	D1 d1;	//声明D1类对象

	B0 *p;	//声明B0类指针

	p = &b0;	//B0类指针指向B0类对象
	fun(p);
	p = &b1;	//B0类指针指向B1类对象
	fun(p);
	p = &d1;	//B0类指针指向D1类对象
	fun(p);
}

2> 输出结果

☆ C++ 继承与派生

3> 结果分析以及多层派生存储方式理解

☆ C++ 继承与派生

 

 

七:多继承

1> 举例

#include <iostream>
using namespace std;

class A {
public:
	void setA(int);
	void showA();
private:
	int a;
};
class B {
public:
	void setB(int);
	void showB();
private:
	int b;
};
class C : public A, private B {
public:
	void setC(int, int, int);
	void showC();
private:
	int c;
};
void  A::setA(int x)
{
	a = x;
}
void A::showA(){
	cout << a << endl;
}
void B::setB(int x)
{
	b = x;
}
void B::showB() {
	cout << b << endl;
}
void C::setC(int x, int y, int z)
{   //派生类成员直接访问基类的
	//公有成员
	setA(x);
	setB(y);
	c = z;
}
void C::showC() {
	cout << c << endl;
}

int main()
{
	C obj;
	obj.setA(5);
	obj.showA();
	// obj.setB(6);  //错误,因为B被私有继承,使用对象无法访问B类中的任何数据成员
	// obj.showB(); //错误
	obj.setC(6, 7, 9);
	obj.showC();
	return 0;
}

2> 多继承的语法格式

☆ C++ 继承与派生

 

 

八:多继承时派生类的构造函数

☆ C++ 继承与派生

1> 多继承时继承类含有内嵌对象,此时构造函数调用顺序 (基类构造函数->内嵌构造函数->本身构造函数 )

☆ C++ 继承与派生

  -->>举例:

#include <iostream>
using namespace std;

class B1	//基类B1,构造函数有参数
{
public:
	B1(int i) { cout << "constructing B1 " << i << endl; }
};
class B2	//基类B2,构造函数有参数
{
public:
	B2(int j) { cout << "constructing B2 " << j << endl; }
};
class B3	//基类B3,构造函数无参数
{
public:
	B3() { cout << "constructing B3 *" << endl; }
};
class C : public B2, public B1, public B3
{
public:	//派生类的公有成员
	C(int a, int b, int c, int d) :
		B1(a), memberB2(d), memberB1(c), B2(b) { }
private:	//派生类的私有对象成员
	B1 memberB1;
	B2 memberB2;
	B3 memberB3;
};
void main()
{
	C obj(1, 2, 3, 4);
}

2> 输出结果

☆ C++ 继承与派生

3> 具体输出顺序分析 (与构造函数中的声明顺序无关 )

☆ C++ 继承与派生

 

 

 

 

相关文章: