inheritWord下载.docx

上传人:b****6 文档编号:18908354 上传时间:2023-01-02 格式:DOCX 页数:11 大小:25.16KB
下载 相关 举报
inheritWord下载.docx_第1页
第1页 / 共11页
inheritWord下载.docx_第2页
第2页 / 共11页
inheritWord下载.docx_第3页
第3页 / 共11页
inheritWord下载.docx_第4页
第4页 / 共11页
inheritWord下载.docx_第5页
第5页 / 共11页
点击查看更多>>
下载资源
资源描述

inheritWord下载.docx

《inheritWord下载.docx》由会员分享,可在线阅读,更多相关《inheritWord下载.docx(11页珍藏版)》请在冰豆网上搜索。

inheritWord下载.docx

Derived*pd=&

base;

//Error,派生类指针指向基类对象;

pb->

show();

//Ok,但输出derived;

print();

//Error.不可调用仅派生类有的方法;

typedefvoid(Derived:

:

*Pderived)();

Pderivedpmend=&

Base:

show;

//Ok,基类成员的指针赋值给派生类成员的指针

(derived.*pmend)();

//使用派生类成员指针

typedefvoid(Base:

*Pbase)();

Pbasepmenb=&

Derived:

//Error.派生类成员的指针赋值给基类成员的指针

}

reinterpret_cast,C-stylecastorfunction-stylecast

dynamic_cast

  

  classB{/*......*/virtualvoidf();

  classV{/*......*/virtualvoidg();

  classX{/*novirtualfunctions*/};

  classD:

publicB,publicvirtualV,publicvirtualX{

  //...

  };

  voidfoo(D&

d)

  {

  B*pb=&

d;

  D*p1=(D*)pb;

//ok,unchecked

  D*p2=dynamic_cast<

D*>

(pb);

//ok,run-timechecked

  V*pv=&

  D*p3=(D*)pv;

//error:

cannotcastfromvirtualbase

  D*p4=dynamic_cast<

(pv);

  X*px=&

  D*p5=(D*)px;

  D*p6=dynamic_cast<

(px);

can'

tcastfromnon-polymorphictype

  }

1.reinterpret_cast可以转换任意一个32bit整数,包括所有的指针和整数。

可以把任何整数转成指针,也可以把任何指针转成整数,以及把指针转化为任意类型的指针,威力最为强大!

但不能将非32bit的实例转成指针。

总之,只要是32bit的东东,怎么转都行!

2.static_cast和dynamic_cast可以执行指针到指针的转换,或实例本身到实例本身的转换,但不能在实例和指针之间转换。

static_cast只能提供编译时的类型安全,而dynamic_cast可以提供运行时类型安全。

举个例子:

3.class 

a;

class 

b:

c。

4.上面三个类a是基类,b继承a,c和ab没有关系。

5.有一个函数void 

function(a&

a);

6.现在有一个对象是b的实例b,一个c的实例c。

7.function(static_cast<

a&

>

(b)可以通过而function(static<

(c))不能通过编译,因为在编译的时候编译器已经知道c和a的类型不符,因此static_cast可以保证安全。

8.下面我们骗一下编译器,先把c转成类型a 

9.b&

ref_b 

reinterpret_cast<

b&

c;

10.然后function(static_cast<

(ref_b))就通过了!

因为从编译器的角度来看,在编译时并不能知道ref_b实际上是c!

11.而function(dynamic_cast<

(ref_b))编译时也能过,但在运行时就失败了,因为dynamic_cast在运行时检查了ref_b的实际类型,这样怎么也骗不过去了。

12.在应用多态编程时,当我们无法确定传过来的对象的实际类型时使用dynamic_cast,如果能保证对象的实际类型,用static_cast就可以了。

至于reinterpret_cast,我很喜欢,很象c语言那样的暴力转换:

) 

13.dynamic_cast:

动态类型转换 

14.static_cast:

静态类型转换 

15.reinterpret_cast:

重新解释类型转换 

16.const_cast:

常量类型转换 

17.synamic_cast一般用在父类和子类指针或应用的互相转化;

18.static_cast一般是普通数据类型(如int 

m=static_cast<

int>

(3.14));

19.reinterpret_cast很像c的一般类型转换操作 

20.const_cast是把cosnt或volatile属性去掉 

21. 

22.. 

23. 

24.泛型(Generic 

Types) 

25. 

26. 

float 

12.3;

27. 

float* 

pf 

&

f;

28. 

// 

static 

cast<

29. 

成功编译, 

12 

30. 

int 

static_cast<

(f);

31. 

错误,指向的类型是无关的(译注:

即指针变量pf是float类型,现在要被转换为int类型) 

//int* 

pn 

int*>

(pf);

32. 

//成功编译 

33. 

void* 

pv 

void*>

34. 

//成功编译, 

但是 

*pn2是无意义的内存(rubbish) 

35. 

int* 

pn2 

36. 

37. 

//错误,编译器知道你应该调用static_cast<

38. 

//int 

39. 

*pn 

实际上是无意义的内存,和 

*pn2一样 

40. 

pi 

简而言之,static_cast<

将尝试转换,举例来说,如float-到-integer,而reinterpret_cast<

简单改变编译器的意图重新考虑那个对象作为另一类型。

41. 

42.指针类型(Pointer 

43. 

44.class 

CBaseX 

45. 

46. 

public:

47. 

x;

48. 

CBaseX() 

10;

49. 

void 

foo() 

printf("

CBaseX:

x=%d/n"

 

x);

50. 

51. 

CBaseY 

52. 

53. 

54. 

y;

55. 

py;

56. 

CBaseY() 

20;

py 

57. 

bar() 

CBaseY:

y=%d, 

*py=%d/n"

y, 

*py);

58. 

59. 

60. 

CDerived 

public 

CBaseX, 

61. 

62. 

63. 

z;

64. 

情况1:

两个无关的类之间的转换 

65. 

66. 

67. 

Convert 

between 

CBaseX* 

and 

CBaseY* 

68. 

和 

CBaseY*之间的转换 

69. 

pX 

new 

CBaseX();

70. 

Error, 

types 

pointed 

to 

are 

unrelated 

71. 

错误, 

类型指向是无关的 

72. 

CBaseY* 

pY1 

CBaseY*>

(pX);

73. 

Compile 

OK, 

but 

pY2 

is 

not 

CBaseX 

74. 

不是CBaseX 

75. 

76. 

System 

crash!

!

77. 

系统崩溃!

78. 

pY2->

bar();

正如我们在泛型例子中所认识到的,如果你尝试转换一个对象到另一个无关的类static_cast<

将失败,而reinterpret_cast<

就总是成功“欺骗”编译器:

那个对象就是那个无关类。

79. 

80.情况2:

转换到相关的类 

81. 

82. 

1. 

CDerived* 

pD 

CDerived();

83. 

2. 

%x/n"

(int)pD);

84. 

3. 

85. 

4. 

->

CDerived* 

86. 

//成功编译,隐式static_cast<

转换 

87. 

5. 

pD;

88. 

6. 

(int)pY1);

89. 

现在 

pD1 

pD 

90. 

7. 

CDerived*>

(pY1);

91. 

8. 

(int)pD1);

92. 

9. 

93. 

10. 

reinterpret_cast 

94. 

不是 

95. 

11. 

(pD);

96. 

12. 

(int)pY2);

97. 

13. 

98. 

14. 

无关的 

99. 

15. 

pY3 

CBaseY();

100. 

16. 

(int)pY3);

101. 

成功编译,尽管 

只是一个 

"

新 

CBaseY()"

102. 

17. 

pD3 

(pY3);

103. 

18. 

(int)pD3);

---------------------- 

输出 

--------------------------- 

104. 

392fb8 

105. 

392fbc 

106. 

107. 

108. 

390ff0 

109. 

390fec 

110. 

注意:

在将CDerived*用隐式 

转换到CBaseY*(第5行)时,结果是(指向)CDerived*(的指针向后) 

偏移了4(个字节)(译注:

4为int类型在内存中所占字节数)。

为了知道static_cast<

实际如何,我们不得不要来看一下CDerived的内存布局。

111. 

112.CDerived的内存布局(Memory 

Layout) 

viewplaincopytoclipboardprint?

1.如图所示,CDerived的内存布局包括两个对象,CBaseX 

CBaseY,编译器也知道这一点。

因此,当你将CDerived* 

转换到 

CBaseY*时,它给指针添加4个字节,同时当你将CBaseY*转换到CDerived*时,它给指针减去4。

然而,甚至它即便不是一个CDerived你也可以这样做。

2.当然,这个问题只在如果你做了多继承时发生。

在你将CDerived转换 

到 

CBaseX时static_cast<

是没有区别的。

3. 

4.情况3:

void*之间的向前和向后转换 

5. 

6.因为任何指针可以被转换到void*,而void*可以被向后转换到任何指针(对于static_cast<

转换都可以这样做),如果没有小心处理的话错误可能发生。

7. 

8. 

9. 

10. 

11. 

12. 

pY 

13. 

(int)pY);

14. 

pV1 

pY;

pY 

15. 

(int)pV1);

16. 

pD2 

pY, 

但是我们预期 

17. 

(pV1);

18. 

(int)pD2);

19. 

系统崩溃 

20. 

pD2->

--------------------------- 

22. 

24. 

一旦我们已经转换指针为void*,我们就不能轻易将其转换回原类。

在上面的例子中,从一个void* 

返回CDerived*的唯一方法是将其转换为CBaseY*然后再转换为CDerived*。

26.但是如果我们不能确定它是CBaseY* 

还是 

CDerived*,这时我们不得不用dynamic_cast<

或typeid[2]。

28.注释:

29.1. 

dynamic_cast<

,从另一方面来说,可以防止一个泛型CBaseY* 

被转换到CDerived*。

30.2. 

需要类成为多态,即包括“虚”函数,并因此而不能成为void*。

31.参考:

32.1. 

[MSDN] 

C++ 

Language 

Reference 

-- 

Casting 

33.2. 

Nishant 

Sivakumar, 

Basics 

Use 

casts 

in 

your 

VC++.NET 

programs 

34.3. 

Juan 

Soulie, 

Tutorial:

Type 

使用标准C++的类型转换符:

static_cast、dynamic_cast、reinterpret_cast、和const_cast。

1static_cast

该运算符把expression转换为type-id类型,但没有运行时类型检查来保证转换的安全性。

它主要有如下几种用法:

①用于类层次结构中基类和子类之间指针或引用的转换。

  进行上行转换(把子类的指针或引用转换成基类表示)是安全的;

  进行下行转换(把基类指针或引用转换成子类表示)时,由于没有动态类型检查,所以是不安全的。

不需要有虚函数

②用于基本数据类型之间的转换,如把int转换成char,把int转换成enum。

这种转换的安全性也要开发人员来保证。

③把空指针转换成目标类型的空指针。

④把任何类型的表达式转换成void类型。

static_cast不能转换掉expression的const、volitale、或者__unaligned属性。

2dynamic_cast

用法:

dynamic_cast<

type-id>

(expression)

该运算符把expression转换成type-id类型的对象。

Type-id必须是类的指针、类的引用或者void*;

dynamic_cast主要用于类层次间的上行转换和下行转换,还可以用于类之间的交叉转换。

在进行下行转换时,dynamic_cast具有类型检查的功能,比static_cast更安全。

classB{

intm_iNum;

virtualvoidfoo();

classD:

publicB{

char*m_szName[100];

voidfunc(B*pb){

D*pd1=static_cast<

D*>

D*pd2=dynamic_cast<

在上面的代码段中,如果pb指向一个D类型的对象,pd1和pd2是一样的,并且对这两个指针执行D类型的任何操作都是安全的;

但是,如果pb指向的是一个B类型的对象,那么pd1将是一个指向该对象的指针,对它进行D类型的操作将是不安全的(如访问m_szName),

而pd2将是一个空指针。

dynamic_cast使用时要有虚函数,否则会编译出错;

static_cast则

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 自然科学

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1