天天看点

C/C++细节问题(bug调试)以动态绑定代码来示例

在程序界,有句话是,程序好些,bug难调。

很多bug并不一点是逻辑错误,而是一些细节问题。

我们分析下三个细节错误引起的无法运行问题:

1

<code>//#define M_PI 3. 14159265358979323846      3.14中间有个空格</code>

<code>\t        写成了\ t       有个空格</code>

首先,创建了一个新类型CFigure。我们想创建一些具体的图形(如,三角形、正方形或者圆),以及计算这些图形周长和面积的方法。但是,我们并不知道具体的图形是什么类型,所以无法用方法直接计算图形的这些特性。这就是要把CFigure类创建为抽象类的原因。抽象类是至少声明了一个虚方法的类,该虚方法没有实现,且其原型后面有=0。以这种方式声明的函数叫做纯虚函数。抽象类不能有对象,但是可以有继承类。因此可以实例化抽象类的指针和引用,然后从CFigure类派生出CTriangle、CSquare和CCircle类,分别表示三角形、正方形和圆形。

我们要实例化这些对象的类型,所以在这些派生类中,实现了FigureType方法、Circumference方法和Area方法。虽然这3个类中的方法名都相同,但是它们的实现不同,这与覆盖类似但含义不同。

如何理解?在本例的main函数中,声明了一个数组,内含3个CFigure类型的指针。作为指向基类的指针或引用,它们一定可以指向该基类的任何派生类。因此,可以创建一个CTriangle类型的对象,并设置CFigure类型的指针指向它,

<code>CFigure* figures[3];</code>

同理,用下面的代码可以设置其他图形:

2

3

<code>figures[0] = </code><code>new</code> <code>CTriangle(2.1,3.2,4.3);</code>

<code>figures[1] = </code><code>new</code> <code>CSquare(5.4,6.6);</code>

<code>figures[2] = </code><code>new</code> <code>CCircle(8.9);</code>

现在,考虑下面的代码:

4

5

6

7

<code>for</code> <code>(</code><code>int</code> <code>i = 0; i &lt; 3; i++)</code>

<code>    </code><code>{</code>

<code>        </code><code>cout &lt;&lt; </code><code>"Figure type:\t"</code> <code>&lt;&lt; figures[i]-&gt;FigureType();</code>

<code>        </code><code>cout&lt;&lt; </code><code>"\nCircumference:\t"</code> <code>&lt;&lt; figures[i]-&gt;Circumference();</code>

<code>        </code><code>cout&lt;&lt; </code><code>"\nArea:\t\t"</code> <code>&lt;&lt; figures[i]-&gt;Area();</code>

<code>        </code><code>cout&lt;&lt; endl &lt;&lt; endl;</code>

<code>    </code><code>}</code>

编译器将使用C++的动态绑定(dynamicbinding)特性,确定图形指针具体指向哪个类型的对象,调用合适的虚方法。只有把方法声明为虚方法,且通过指针或引用访问才能使用动态绑定。

全部代码如下,直接可以编译运行:

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

86

87

88

89

90

91

92

93

94

95

96

97

98

99

100

101

102

103

104

105

106

107

108

109

110

111

112

113

114

115

116

117

118

119

120

121

122

123

124

125

126

<code>#include "stdafx.h"</code>

<code>#include &lt; iostream&gt;</code>

<code>#include &lt;tchar.h&gt; </code>

<code>#define M_PI 3.14159265358979323846</code>

<code>using</code> <code>namespace</code> <code>std;</code>

<code>class</code> <code>CFigure  </code><code>//base class</code>

<code>{</code>

<code>public</code><code>:</code>

<code>    </code><code>virtual</code> <code>char</code><code>* FigureType() = 0;</code>

<code>    </code><code>virtual</code> <code>double</code> <code>Circumference() = 0;</code>

<code>    </code><code>virtual</code> <code>double</code> <code>Area() = 0;</code>

<code>    </code><code>virtual</code> <code>~CFigure()</code>

<code>    </code><code>{ </code>

<code>    </code> 

<code>};</code>

<code>class</code> <code>CTriangle : </code><code>public</code> <code>CFigure </code><code>//Derived Class</code>

<code>    </code><code>CTriangle()</code>

<code>        </code><code>a = b = c = 0;</code>

<code>    </code><code>CTriangle(</code><code>double</code> <code>a, </code><code>double</code> <code>b, </code><code>double</code> <code>c) : a(a), b(b), c(c) { }</code>

<code>    </code><code>virtual</code> <code>char</code><code>* FigureType()</code>

<code>        </code><code>return</code> <code>"Triangle"</code><code>;</code>

<code>    </code><code>virtual</code> <code>double</code> <code>Circumference()</code>

<code>        </code><code>return</code> <code>a + b + c;</code>

<code>    </code><code>virtual</code> <code>double</code> <code>Area()</code>

<code>        </code><code>double</code> <code>S = Circumference() / 2;</code>

<code>        </code><code>return</code> <code>sqrt</code><code>(S * (S - a) * (S - b) * (S - c));</code>

<code>private</code><code>:</code>

<code>    </code><code>double</code> <code>a, b, c;</code>

<code>class</code> <code>CSquare : </code><code>public</code> <code>CFigure  </code><code>//Derived Class</code>

<code>    </code><code>CSquare()</code>

<code>        </code><code>a = 0.0;</code>

<code>        </code><code>b = 0.0;</code>

<code>    </code><code>CSquare(</code><code>double</code> <code>a, </code><code>double</code> <code>b) : a(a), b(b)</code>

<code>        </code><code>return</code> <code>"Square"</code><code>;</code>

<code>        </code><code>return</code> <code>2 * a + 2 * b;</code>

<code>        </code><code>return</code> <code>a * b;</code>

<code>    </code><code>double</code> <code>a, b;</code>

<code>class</code> <code>CCircle : </code><code>public</code> <code>CFigure </code><code>//Derived Class</code>

<code>    </code><code>double</code> <code>r;</code>

<code>    </code><code>CCircle()</code>

<code>        </code><code>r = 0;</code>

<code>    </code><code>CCircle(</code><code>double</code> <code>r) : r(r)</code>

<code>        </code><code>return</code> <code>"Circle"</code><code>;</code>

<code>        </code><code>//return 2 * r * M_PI;</code>

<code>        </code><code>double</code> <code>res = 0.00000000000000000000000;</code>

<code>        </code><code>res = 2 * r * M_PI;</code>

<code>        </code><code>//res = 2 * r *  3. 141592;</code>

<code>        </code><code>return</code> <code>res;</code>

<code>        </code><code>double</code> <code>res = 0.000000000000000000000;</code>

<code>        </code><code>//res = 2 * r *  3. 14159265358979323846;</code>

<code>int</code> <code>_tmain(</code><code>int</code> <code>argc, _TCHAR* argv[]) </code>

<code>    </code><code>CFigure* figures[3];</code>

<code>    </code><code>figures[0] = </code><code>new</code> <code>CTriangle(2.1,3.2,4.3);</code>

<code>    </code><code>figures[1] = </code><code>new</code> <code>CSquare(5.4,6.6);</code>

<code>    </code><code>figures[2] = </code><code>new</code> <code>CCircle(8.9);</code>

<code>    </code><code>for</code> <code>(</code><code>int</code> <code>i = 0; i &lt; 3; i++)</code>

<code>    </code><code>getchar</code><code>();</code>

<code>    </code><code>return</code> <code>0;</code>

<code>}</code>

运行结果:

<a href="https://s1.51cto.com/wyfs02/M01/A4/C2/wKioL1mw88jhKufqAADRNwBXBuc826.jpg-wh_500x0-wm_3-wmp_4-s_975914462.jpg" target="_blank"></a>

本文转自 liam2199 博客,原文链接:  http://blog.51cto.com/liam2199/1963425         如需转载请自行联系原作者

继续阅读