C++中基类和派生类之间的转换实例教程

2025-05-27 0 31

本文实例讲解了C++基类派生类之间的转换。对于深入理解C++面向对象程序设计有一定的帮助作用。此处需要注意:本文实例讲解内容的前提是派生类继承基类的方式是公有继承,关键字public。具体分析如下:

以下程序为讲解示例:

?

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

83

84

85
#include<iostream>

using namespace std;

class A

{

public:

A(int m1, int n1):m(m1), n(n1){}

void display();

private:

int m;

int n;

};

void A::display()

{

cout << "m = " << m << endl;

cout << "n = " << n << endl;

}

class B :public A

{

public:

B(int m1, int n1, int p1) :A(m1, n1), p(p1){}

void display();

private:

int p;

};

void B::display()

{

A::display();

cout << "p = " << p << endl;

}

void print1(A& a)

{

a.display();

}

void print2(B& b)

{

b.display();

}

void print3(A a)

{

a.display();

}

void print4(B b)

{

b.display();

}

int main()

{

A a(3, 4);

// a.display();

B b(10, 20, 30);

// b.display();

A * pa;

B * pb;

pa = &a;

// pa->display();

pb = &b;

// pb->display();

// pa = &b;

// pa->display();

// pb = &a; //错误。派生类指针不能指向基类对象。

// print1(b);

// print2(a); //错误。不能用基类对象给派生类引用赋值。

// print3(b);

// print4(a); //错误。不能用基类对象给派生类对象赋值。

// pb = pa; //不能用基类指针给派生类指针赋值。

pb = (B*)pa; //可以强制转换,但是非常不安全。

pb->display(); //出现安全问题,p无法访问,因为a中没有p成员

system("pause");

return 0;

}

切记:派生类对象是基类对象,派生类中包含有基类的成员。基类对象不是派生类对象,它不能包含派生类型的成员。

一、派生类基类的转化

1.派生类对象地址赋值给基类指针

main函数中执行以下代码

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14
A a(3, 4);

// a.display();

B b(10, 20, 30);

// b.display();

A * pa;

// B * pb;

// pa = &a;

// pa->display();

// pb = &b;

// pb->display();

pa = &b;

pa->display(); //会输出 10 20

pa为基类指针,指向派生类对象是合法的,因为派生类对象也是基类对象。语句会输出派生类对象中基类部分。

注意:这里并不会调用派生类的display函数,调用的是基类的display函数,因为指针pa是基类指针,编译器在编译阶段只知道pa的类型。如果要实现调用派生类的display函数,需要用到虚函数实现多态性。之后的文章会讲到。

进一步解释一下编译时和运行时的区别。

编译时编译器能知道pa的类型为A *,但是不知道它指向了哪个对象,假如有以下语句

?

1

2

3

4

5

6

7

8

9
A a(3, 4);

B b(10, 20, 30);

A* pa;

int number;

cin >> number;

if (number >= 0)

pa = &a;

else

pa = &b;

pa指向的对象类型依赖于输入,运行时才输入,所以编译器是没有办法知道pa指向哪个类型的。

2.派生类对象赋值给基类引用

引用跟指针基本没有区别,引用本质上是指针,是个指针常量,具体可以参照我的另一篇C++中的引用和指针的联系和区别

main函数中执行以下代码

?

1

2

3
A a(3, 4);

B b(10, 20, 30);

print1(b); //会输出 10 20

形参为基类引用,实参为派生类对象,派生类对象也是基类对象,可以赋值给基类引用。输出派生类基类部分。

注意:此时对象本身并未复制,b仍然是派生类对象,前面说过了引用就是一个指针

3.派生类对象赋值给基类对象。

?

1

2

3
A a(3, 4);

B b(10, 20, 30);

print3(b);

派生类对象基类部分被复制给形参。

注意:实际上没有从派生类对象到基类对象的直接转换。对基类对象的赋值或初始化,实际上在调用函数,初始化时调用构造函数,赋值时调用赋值操作符。

二、基类派生类的转化

切记:这种转换有可能引发严重的安全问题,编写代码时不要使用。没有基类派生类的自动转换,原因在于基类对象只能是基类对象,不能包含派生类型的成员

如果允许用基类对象给派生类对象赋值,那么就可以试图使用该派生类对象访问不存在的成员。

?

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15
A a(3, 4);

B b(10, 20, 30);

A * pa;

B * pb;

// print2(a); //错误。不能用基类对象给派生类引用赋值。

// print4(a); //错误。不能用基类对象给派生类对象赋值。

// pb = &a; //错误。派生类指针不能指向基类对象。

pa = &a;

pb = &b;

//pb = pa; //错误。不能用基类指针给派生类指针赋值。

pb = (B*)pa; //可以强制转换,但是非常不安全。

pb->display(); //出现安全问题,p无法访问,因为a中没有p成员

注意到我们使用强制转换时,当派生类添加了基类中不存在的成员时,会出现安全问题。

pb->display();会调用派生类的display函数,但是它指向的内存是基类对象a的内存,p不存在。会出现严重后果。

收藏 (0) 打赏

感谢您的支持,我会继续努力的!

打开微信/支付宝扫一扫,即可进行扫码打赏哦,分享从这里开始,精彩与您同在
点赞 (0)

声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。

快网idc优惠网 建站教程 C++中基类和派生类之间的转换实例教程 https://www.kuaiidc.com/75792.html

相关文章

发表评论
暂无评论