龙空技术网

C++继承:继承与构造函数、派生类到基类的转换

爱音乐的程序员小新人 220

前言:

此时大家对“继承类 构造函数怎么写”大致比较重视,我们都需要分析一些“继承类 构造函数怎么写”的相关内容。那么小编在网摘上搜集了一些有关“继承类 构造函数怎么写””的相关知识,希望大家能喜欢,各位老铁们快快来了解一下吧!

一、不能自动继承的成员函数

构造函数(包括拷贝构造函数)

析构函数

=运算符

二、继承与构造函数

基类的构造函数不被继承,派生类中需要声明自己的构造函数。

声明构造函数时,只需要对本类中新增成员进行初始化,对继承来的基类成员的初始化调用基类构造函数完成(如果没有给出则默认调用默认构造函数)。

派生类的构造函数需要给基类的构造函数传递参数

C++ Code

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

75

76

77

78

79

80

81

82

#include <iostream>

using namespace std;

class ObjectB

{

public:

ObjectB(int objb) : objb_(objb)

{

cout << "ObjectB ..." << endl;

}

~ObjectB()

{

cout << "~ObjectB ..." << endl;

}

int objb_;

};

class ObjectD

{

public:

ObjectD(int objd) : objd_(objd)

{

cout << "ObjectD ..." << endl;

}

~ObjectD()

{

cout << "~ObjectD ..." << endl;

}

int objd_;

};

class Base

{

public:

Base(int b) : b_(b), objb_(111)

{

cout << "Base ..." << endl;

}

Base(const Base &other) : objb_(other.objb_), b_(other.b_)

{

}

~Base()

{

cout << "~Base ..." << endl;

}

int b_;

ObjectB objb_;

};

class Derived : public Base

{

public:

Derived(int b, int d) : d_(d), Base(b), objd_(222)

{

cout << "Derived ..." << endl;

}

Derived(const Derived &other) : d_(other.d_), objd_(other.objd_), Base(other)

{

}

~Derived()

{

cout << "~Derived ..." << endl;

}

int d_;

ObjectD objd_;

};

int main(void)

{

Derived d(100, 200);

cout << d.b_ << " " << d.d_ << endl;

Base b1(100);

Base b2(b1);

cout << b2.b_ << endl;

Derived d2(d);

return 0;

}

从输出可以看出:

派生类对象的构造次序:

先调用基类对象成员的构造函数,接着是基类的构造函数,然后是派生类的对象成员的构造函数,最后是派生类自身的构造函数。

也可以这样来看:构造函数执行的顺序是先执行初始化列表,然后是函数体。初始化列表参数多个且其中有调用基类构造函数时,先执行基类构造函数(从最远的开始,如果多重继承则按继承的顺序);其他对象成员若不止一个,则按定义的顺序构造,与初始化列表顺序无关。关于初始化列表可以参考这里

析构的顺序与构造的顺序相反。

三、友元关系、静态成员与继承

友元关系不能被继承

静态成员无所谓继承

C++ Code

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

#include <iostream>

using namespace std;

class Base

{

public:

static int b_;

};

int Base::b_ = 100;

class Derived : public Base

{

};

int main(void)

{

Base b;

Derived d;

cout << Base::b_ << endl;

cout << b.b_ << endl;

cout << Derived::b_ << endl;

cout << d.b_ << endl;

return 0;

}

都能访问,输出100,但推荐使用类::xx 访问,如b.b_ 访问存在歧义,实际上static成员不属于任一对象。

四、派生类到基类的转换

当派生类以public方式继承基类时,编译器可自动执行的转换(向上转型 upcasting 安全转换)

派生类对象指针自动转化为基类对象指针

派生类对象引用自动转化为基类对象引用

派生类对象自动转换为基类对象(特有的成员消失)

当派生类以private/protected方式继承基类时

派生类对象指针(引用)转化为基类对象指针(引用)需用强制类型转化。但不能用static_cast,要用reinterpret_cast

不能把派生类对象强制转换为基类对象

C++ Code

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

67

68

69

70

71

72

73

74

#include <iostream>

#include <string>

using namespace std;

class Employee

{

public:

Employee(const string &name, const int age, const int deptno) : name_(name),

age_(age), deptno_(deptno)

{

}

private:

string name_;

int age_;

int deptno_;

};

class Manager : public Employee

{

public:

Manager(const string &name, const int age, const int deptno, int level)

: Employee(name, age, deptno), level_(level)

{

}

private:

int level_;

};

class Manager2 : private Employee

{

public:

Manager2(const string &name, const int age, const int deptno, int level)

: Employee(name, age, deptno), level_(level)

{

}

private:

int level_;

};

int main(void)

{

Employee e1("zhangsan", 25, 20);

Manager m1("lisi", 38, 20, 10);

Manager2 m2("wangwu", 40, 15, 8);

Employee *pe;

Manager *pm;

Manager2 *pm2;

pe = &e1;

pm = &m1;

pm2 = &m2;

pe = &m1; // 派生类对象指针可以转化为基类对象指针。将派生类对象看成基类对象

//pm = &e1; // 基类对象指针无法转化为派生类对象指针。无法将基类对象看成是派生类对象

e1 = m1; // 派生类对象可以转化为基类对象。将派生类对象看成基类对象

// 会产生对象切割(派生类特有成员消失)。object slicing

//pe = pm2; //私有或保护继承的时候,派生类对象指针不可以自动转化为基类对象指针

pe = reinterpret_cast<Employee *>(pm2);

//e1 = m2; // 私有或保护继承的时候,派生类对象无法转化为基类对象。

//e1 = reinterpret_cast<Employee>(m2); // 私有或保护继承的时候,派生类对象无法强制转化为基类对象。

pm = static_cast<Manager *>(pe); // 基类指针可以强制转化为派生类指针,但是不安全

//m1 = reinterpret_cast<Manager>e1; // 基类对象无法强制转化为派生类对象

return 0;

}

五、基类到派生类的转换

基类对象指针(引用)可用强制类型转换为派生类对象指针(引用), 而基类对象无法执行这类转换.

向下转型不安全,没有自动转换的机制

// 从语法上来演示基类对象可以转化为派生类对象,但是没有意义

1、转换构造函数:

Manager(const Employee& other) : Employee(other), level_(-1)

{

}

2、类型转换运算符:

Employee::operator Manager()

{

return Manager(name_, age_, deptno_, -1);

}

标签: #继承类 构造函数怎么写