C/C++细节问题(bug调试)以动态绑定代码来示例
2017-09-07 15:23
344 查看
在程序界,有句话是,程序好些,bug难调。
很多bug并不一点是逻辑错误,而是一些细节问题。
我们分析下三个细节错误引起的无法运行问题:
首先,创建了一个新类型CFigure。我们想创建一些具体的图形(如,三角形、正方形或者圆),以及计算这些图形周长和面积的方法。但是,我们并不知道具体的图形是什么类型,所以无法用方法直接计算图形的这些特性。这就是要把CFigure类创建为抽象类的原因。抽象类是至少声明了一个虚方法的类,该虚方法没有实现,且其原型后面有=0。以这种方式声明的函数叫做纯虚函数。抽象类不能有对象,但是可以有继承类。因此可以实例化抽象类的指针和引用,然后从CFigure类派生出CTriangle、CSquare和CCircle类,分别表示三角形、正方形和圆形。
我们要实例化这些对象的类型,所以在这些派生类中,实现了FigureType方法、Circumference方法和Area方法。虽然这3个类中的方法名都相同,但是它们的实现不同,这与覆盖类似但含义不同。
如何理解?在本例的main函数中,声明了一个数组,内含3个CFigure类型的指针。作为指向基类的指针或引用,它们一定可以指向该基类的任何派生类。因此,可以创建一个CTriangle类型的对象,并设置CFigure类型的指针指向它,
同理,用下面的代码可以设置其他图形:
全部代码如下,直接可以编译运行:
很多bug并不一点是逻辑错误,而是一些细节问题。
我们分析下三个细节错误引起的无法运行问题:
//#define M_PI 3. 14159265358979323846 3.14中间有个空格
\t 写成了\ t 有个空格
首先,创建了一个新类型CFigure。我们想创建一些具体的图形(如,三角形、正方形或者圆),以及计算这些图形周长和面积的方法。但是,我们并不知道具体的图形是什么类型,所以无法用方法直接计算图形的这些特性。这就是要把CFigure类创建为抽象类的原因。抽象类是至少声明了一个虚方法的类,该虚方法没有实现,且其原型后面有=0。以这种方式声明的函数叫做纯虚函数。抽象类不能有对象,但是可以有继承类。因此可以实例化抽象类的指针和引用,然后从CFigure类派生出CTriangle、CSquare和CCircle类,分别表示三角形、正方形和圆形。
我们要实例化这些对象的类型,所以在这些派生类中,实现了FigureType方法、Circumference方法和Area方法。虽然这3个类中的方法名都相同,但是它们的实现不同,这与覆盖类似但含义不同。
如何理解?在本例的main函数中,声明了一个数组,内含3个CFigure类型的指针。作为指向基类的指针或引用,它们一定可以指向该基类的任何派生类。因此,可以创建一个CTriangle类型的对象,并设置CFigure类型的指针指向它,
CFigure* figures[3];
同理,用下面的代码可以设置其他图形:
figures[0] = new CTriangle(2.1,3.2,4.3); figures[1] = new CSquare(5.4,6.6); figures[2] = new CCircle(8.9);现在,考虑下面的代码:
for (int i = 0; i < 3; i++) { cout << "Figure type:\t" << figures[i]->FigureType(); cout<< "\nCircumference:\t" << figures[i]->Circumference(); cout<< "\nArea:\t\t" << figures[i]->Area(); cout<< endl << endl; }编译器将使用C++的动态绑定(dynamicbinding)特性,确定图形指针具体指向哪个类型的对象,调用合适的虚方法。只有把方法声明为虚方法,且通过指针或引用访问才能使用动态绑定。
全部代码如下,直接可以编译运行:
#include "stdafx.h"运行结果:
#include < iostream>
#include <tchar.h>
#define M_PI 3.14159265358979323846
using namespace std;
//#define M_PI 3. 14159265358979323846 3.14中间有个空格
class CFigure //base class
{
public:
virtual char* FigureType() = 0;
virtual double Circumference() = 0;
virtual double Area() = 0;
virtual ~CFigure()
{
}
};
class CTriangle : public CFigure //Derived Class
{
public:
CTriangle()
{
a = b = c = 0;
}
CTriangle(double a, double b, double c) : a(a), b(b), c(c) { }
virtual char* FigureType()
{
return "Triangle";
}
virtual double Circumference()
{
return a + b + c;
}
virtual double Area()
{
double S = Circumference() / 2;
return sqrt(S * (S - a) * (S - b) * (S - c));
}
private:
double a, b, c;
};
class CSquare : public CFigure //Derived Class
{
public:
CSquare()
{
a = 0.0;
b = 0.0;
}
CSquare(double a, double b) : a(a), b(b)
{
}
virtual char* FigureType()
{
return "Square";
}
virtual double Circumference()
{
return 2 * a + 2 * b;
}
virtual double Area()
{
return a * b;
}
private:
double a, b;
};
class CCircle : public CFigure //Derived Class
{
private:
double r;
public:
CCircle()
{
r = 0;
}
CCircle(double r) : r(r)
{
}
virtual char* FigureType()
{
return "Circle";
}
virtual double Circumference()
{
//return 2 * r * M_PI;
double res = 0.00000000000000000000000;
res = 2 * r * M_PI;
//res = 2 * r * 3. 141592;
return res;
}
virtual double Area()
{
double res = 0.000000000000000000000;
res = 2 * r * M_PI;
//res = 2 * r * 3. 14159265358979323846;
return res;
}
};
int _tmain(int argc, _TCHAR* argv[])
{
CFigure* figures[3];
figures[0] = new CTriangle(2.1,3.2,4.3);
figures[1] = new CSquare(5.4,6.6);
figures[2] = new CCircle(8.9);
for (int i = 0; i < 3; i++) { cout << "Figure type:\t" << figures[i]->FigureType(); cout<< "\nCircumference:\t" << figures[i]->Circumference(); cout<< "\nArea:\t\t" << figures[i]->Area(); cout<< endl << endl; }
getchar();
return 0;
}
相关文章推荐
- c/c++中动态内存分配处理字符串的细节问题
- C++ 两个有趣的问题(静态动态绑定,和类指针指向空的实质)
- c++调试UnitTest(问题代码在so库里)的方法
- Android studio 调试NDK C++ 代码,遇到的问题
- C++多重继承下的函数动态绑定问题分析
- AS调试opencv示例代码,尝试解决camera2包报错的问题
- Bug(已解决,不是代码问题):调试停在objcore.cpp
- C#不能调试非托管C++代码问题
- 示例:日志调试工具EurekaLog(检查代码Bug)
- Java动态规划之编辑距离问题示例代码
- 0-1背包问题动态规划代码实现(C++实现)
- C++中的动态绑定问题
- C++实现动态绑定代码分享
- VS2015 C#调用C++ 托管代码无法调试问题排查
- 【逆向知识】动态调试技巧-C++代码逆向
- Cocos2d-x使用Javascript开发js绑定C++<代码示例>
- 0-1背包问题与动态规划的C/C++代码
- 关于多态性的动态绑定问题, 对象调用方法的执行过程.
- 一个简单C++的调试代码
- zz一个VS2005无法调试C++的问题