C++实用技巧
复杂的东西写多了,如今写点简单的好了。由于功能上的需要,Vczh Library++3.0被我搞得很离谱。为了开发维护的遍历、减少粗心犯下的错误以及增强单元测试、回归测试和测试工具,因此记录下一些开发上的小技巧,以便抛砖引玉,造福他人。欢迎高手来喷C++实谓各种语言中的软肋,功能强大,陷阱更强大。当然我认为一门语言用得不好完全是程序员的责任,不过因为C++涉及到的概念实在是太多,想用好实在也不是一件容易的事情。C++开发的时候总是会遇到各种各样的问题,其中最严重的无非是内存相关的。C语言由于结构简单,内存处理起来虽然不得力,但总的来说惯用法已经深入人心,因此也不会造成什么很难发现的错误。C++就不一样了。有了虚函数、构造函数、析构函数、复制构造函数和operator=重载之后,还是有很多人喜欢把一个类直接写进文件流,或者拿来memset,代码一团乱麻,不知悔改也。但是不能因此因噎废食,就像某人因为C++带来的心智问题太多,自己搞不定,自己团队也搞不定,就说C++不好一样。
因此第一篇文章主要针对内存来讲。我们处理内存,第一件事就是不要有内存泄露。内存泄露不能等到测试的时候,通过长时间运行程序并观察任务管理器的方法来做,这显然已经晚了。幸好Visual C++给了我们一个十分好用的工具:_CrtDumpMemoryLeaks函数。这
个函数会在Debug模式下往Visual Studio的output窗口打印出那个时候你new(malloc)了但是还没delete(free)的所有内存块的地址、长度、前N个字节的内容和其他信息。怎么做呢?其实很简单:
1 #define _CRTDBG_MAP_ALLOC
2 #include
3 #include
4 #include
5
6 int wmain(vint argc , wchar_t* args[])
7 {
8 // 这里运行程序,并在下面的函数调用之前delete掉所有new的东西
9 _CrtDumpMemoryLeaks();
10 return 0;
11 }
上一篇文章讲到了如何检查内存泄露。其实只要肯用C++的STL里面的高级功能的话,内存泄露是很容易避免的。我在开发Vczh Library++ 3.0的时候,所有的测试用例都保证跑完了没有内存泄露。但是很可惜有些C++团队不能使用异常,更甚者不允许写构造函数析构函数之类,前一个还好,后一个简直就是在用C。当然有这些变态规定的地方STL都是用不了的,所以我们更加需要扎实的基础来开发C++程序。
今天这一篇主要还是讲指针的问题。因为上一篇文章一笔带过,今天就来详细讲内存泄漏或者野指针发生的各种情况。当然我不可能一下子举出全部的例子,只能说一些常见的。
一、错误覆盖内存。
之前提到的不能随便乱memset其实就是为了避免这个问题的。其实memcpy也不能乱用,我们来看一个例子,最简单的:
1 #define MAX_STRING 20;
2
3 struct Student
4 {
5 char name[MAX_STRING];
6 char id[MAX_STRING];
7 int chinese;
8 int math;
9 int english;
10 };
大家对这种结构肯定十分熟悉,毕竟是大学时候经常要写的作业题……好了,大家很容易看得出来这其实是C语言的经典写法。我们拿到手之后,一般会先初始化一下,然后赋值。
1 Student vczh;
2 memset(&vczh, 0, sizeof(vczh));
3 strcpy(vczh.name, "vczh");
4 strcpy(vczh.id, "VCZH'S ID");
5 vczh.chinese=70;
6 vczh.math=90;
lish=80;
析构方法为什么要在这里使用memset呢?memset的用处是将一段内存的每一个字节都设置成同一个数字。这里是0,因此两个字符串成员的所有字节都会变成0。因此在memset了Student之后,我们通过正常
方法来访问name和id的时候都会得到空串。而且如果Student里面有指针的话,0指针代表的是没有指向任何有效对象,因此这个时候对指针指向的对象进行读写就会立刻崩溃。对于其他数值,0一般作为初始值也不会有什么问题(double什么的要小心)。这就是我们写程序的时候使用memset的原因。
今天是关于内存的最后一篇了。上一篇文章讲了为什么不能对一个东西随便memset。里面的demo代码出了点小bug,不过我不喜欢在发文章的时候里面的demo代码也拿去编译和运行,所以大家有什么发现的问题就评论吧。这样也便于后来的人不会受到误导。这次说的仍然是构造函数和析构函数的事情,不过我们将通过亲手开发一个智能指针的方法,知道引用计数如何帮助管理资源,以及错误使用引用计数的情况。
首先先来看一下智能指针是如何帮助我们管理内存的。现在智能指针的实现非常多,我就假设这个类型
叫Ptr吧。这跟Vczh Library++ 3.0所使用的实现一样。
1 class Base
2 {
3 public:
4 virtual ~Base(){}
5 };
6
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论