目录:
- 启用所有警告和错误消息
- <! --3 - >
- 作为程序员,您必须了解您的程序在做什么。程序输出期望值是不够的。你需要了解你的程序正在做的一切。没有什么能让你更好地感觉到程序中发生了什么,而不是单步执行
- 最后,当一个功能完成并准备添加到程序中时,每个逻辑路径至少需要经过一次。当你自己检查函数时,而不是在函数的其余部分被抛入函数之后,错误更容易找到 - 那么,你的注意力已经面临新的编程挑战。
- 如果可能的话,MyClass应该自己跟踪这些内存指针,并在析构函数中删除它们。
- 如果您将不再有效的指针归零,并尝试使用它们来存储值(不能在null位置或其附近存储任何内容),那么程序将立即崩溃。崩溃听起来不好,但它不是如果它暴露出一个问题。问题在那里;这只是在投入生产之前是否找到的问题。
- 声明析构函数virtual
- 提供一个拷贝构造函数和重载赋值操作符
视频: What is a HashTable Data Structure - Introduction to Hash Tables , Part 0 2024
这是一个不幸的事实,您将花费更多的时间来搜索和删除错误,而不是花在实际编写C ++程序时。这里的建议可能会帮助您最大限度地减少引入到程序中的错误数量,从而使编程更加愉快。
启用所有警告和错误消息
C ++的语法允许进行大量的错误检查。当编译器遇到一个它无法破译的结构时,它只能输出一个消息。它会尝试与源代码进行备份(有时不会成功),但不会生成可执行文件。这迫使程序员修复所有的错误信息。
<!然而,当C ++遇到一个它可以计算出来的结构,但是结构仍然有异味时,C ++会生成一个警告消息。因为C ++非常确定它能够理解你想要的东西,所以它会继续并创建一个可执行文件,所以如果你喜欢,你可以忽略警告。事实上,如果你真的不想被打扰,你可以禁用警告。禁用或以其他方式忽略警告是一个非常糟糕的主意。这有点像拔掉汽车仪表盘上的“检查引擎”指示灯,因为它困扰着你。忽视这个问题并不会让它消失。<!采用清晰和一致的编码风格
以清晰一致的风格编写C ++代码不仅可以提高程序的可读性,还可以减少编码错误。这种有些令人惊讶的事态是由于我们的大脑只有有限的计算能力。
当你阅读干净整洁的代码,并遵循你熟悉的风格时,你会花费很少的脑力去分析C ++语句的语法。这就让更多的大脑CPU能够解码程序正在做什么,而不是解释程序如何做。一种好的编码风格可以让你轻松完成以下工作:
区分类名,对象名和函数名
了解类,函数或对象用于,根据其名称区分C ++符号中的预处理符号(也就是#define对象应该突出显示)
-
识别相同级别的C ++代码块(这是缩进一致的结果)
-
In此外,您需要为模块标头建立标准格式,以提供有关每个模块中的功能或类别,作者,日期,版本以及有关修改历史记录的信息。所有涉及单个项目的程序员都应该使用相同的编码风格。用不同编码风格拼成的程序很混乱,看起来不专业。
-
在编写代码时注释代码
-
如果在编写代码时注释代码,则可以避免错误,而不是等到一切正常后再返回并添加注释。
制定评论迫使你评估你正在做什么。简短的评论是启发性的,无论是当你阅读他们后,当你写他们。写评论,就好像你正在和另一个知识渊博的程序员谈话。
在调试器中至少执行一次每个路径
作为程序员,您必须了解您的程序在做什么。程序输出期望值是不够的。你需要了解你的程序正在做的一切。没有什么能让你更好地感觉到程序中发生了什么,而不是单步执行
程序,用一个好的调试器(如Code:: Blocks)来执行它。
除此之外,当你调试一个程序时,你需要原材料来找出程序运行时可能出现的一些奇怪的行为。没有什么比单步执行每个功能更好的材料。
最后,当一个功能完成并准备添加到程序中时,每个逻辑路径至少需要经过一次。当你自己检查函数时,而不是在函数的其余部分被抛入函数之后,错误更容易找到 - 那么,你的注意力已经面临新的编程挑战。
限制可见性 限制类内部对外部世界的可见性是面向对象编程的基石。课堂应该对内部状态负责 - 如果课堂上有些事情搞砸了,那么这是班级程序员的错。应用程序员应该担心解决手头的问题。 具体来说,有限的可视性意味着数据成员不应该在课堂外访问 - 也就是说,他们应该被标记为受保护的。另外,应用软件不需要知道的成员函数也应该被标记保护。为了完成工作,不要再暴露出更多的内部工作。
记录堆内存
丢失堆内存轨道是已经发布到现场的程序中最常见的致命错误来源 - 同时也是追查和删除最难的问题。 (因为这类错误很难找到和删除,所以在你购买的程序中很普遍。)在出现问题之前,可能需要运行一个程序几个小时(取决于内存泄漏的程度)。一般来说,程序员应该总是在相同的层次上分配和释放堆内存。 “如果成员函数MyClass:: create()分配了一块堆内存并将其返回给调用者,那么应该有一个成员MyClass:: release()将其返回给堆。具体来说,MyClass:: create()不应该要求父函数释放内存。
如果可能的话,MyClass应该自己跟踪这些内存指针,并在析构函数中删除它们。
在删除指向
之后清零指针确保在指针不再有效之后将其清零;你可以通过赋值nullptr来完成。这个行为的原因变得很清晰:你可以继续使用已经返回堆的内存块,甚至不知道它。一个程序可能在99%的时间内正常运行,这使得很难找到1%的块被重新分配和程序不工作的情况。
如果您将不再有效的指针归零,并尝试使用它们来存储值(不能在null位置或其附近存储任何内容),那么程序将立即崩溃。崩溃听起来不好,但它不是如果它暴露出一个问题。问题在那里;这只是在投入生产之前是否找到的问题。
使用异常来处理错误
C ++中的异常机制旨在方便有效地处理错误。一般来说,您应该抛出错误指示符,而不是返回错误标志。生成的代码更易于编写,读取和维护。另外,其他程序员也期待它,你不想让他们失望,对不对?
将您对异常的使用限制为真正的错误。如果这是该功能的日常生活的一部分,则不需要从返回“不工作”指示符的函数中抛出异常。
声明析构函数virtual
如果构造函数分配资源,如堆对象达到最终消亡时需要返回的资源,请不要忘记为您的类创建一个析构函数。创建了一个析构函数后,别忘了声明它是虚拟的。 “”但是,“你说,”我的班级没有从任何东西继承,也没有被另一个班级继承。 “是的,但是
可能会在未来成为基础班。除非你有一些很好的理由没有声明析构函数是虚拟的,那么当你第一次创建这个类的时候就这样做了。
提供一个拷贝构造函数和重载赋值操作符
如果你的类需要析构函数,那么它肯定需要一个拷贝构造函数和一个重载赋值操作符。如果您的构造函数分配资源(如堆内存),则默认的复制构造函数和赋值运算符将不会执行任何操作,而是通过生成指向相同资源的多个指针来创建混乱。
当这些对象的析构函数被调用时,它将恢复资产。当另一个副本的析构函数出现时,它会把事情搞砸。