C程序员开始编写C ++有什么坏习惯?

时间:2010-08-17 11:00:04

标签: c++ c

最近的讨论结束时嘲笑程序员的坏习惯,当他们开始用另一种语言编程时,他们暴露于某种语言。最好的例子是Pascal程序员在开始编写C时开始#define begin {#define end }

目标是在开始使用C ++时尝试捕捉C程序员的坏习惯。

告诉您遇到的大。请回答一个建议,试图实现一种最好的。

对于那些对良好习惯感兴趣的人,请查看对此question的接受答案。

23 个答案:

答案 0 :(得分:51)

使用原始指针和资源而不是RAII对象。

答案 1 :(得分:38)

  • 使用char *而不是std :: string
  • 使用数组而不是std :: vector(或其他容器)
  • 不使用其他STL算法或库,如适当的提升
  • 滥用预处理器,其中常量,typedef或模板会更好
  • 编写SESE风​​格(单项单退出)代码

答案 2 :(得分:30)

声明函数顶部的所有变量,而不是尽可能接近它们的位置。

答案 3 :(得分:18)

不使用STL,特别是std :: string,

和/或

使用std :: strings并在紧急角落恢复旧c字符串函数。

答案 4 :(得分:18)

  1. 编写2000行代码的类定义。
  2. 将该类定义复制并粘贴到12个不同的位置。
  3. 使用简单虚拟方法时的switch语句。
  4. 无法在构造函数中分配内存并在析构函数中释放。
  5. 采用可选参数的虚方法。
  6. 编写while循环来操作char *字符串。
  7. 编写长度为页面的巨型宏。 (本来可以使用模板)。

答案 5 :(得分:17)

使用指针而不是引用

答案 6 :(得分:17)

using添加到头文件中,以便在类型声明中避免使用std::string之类的名称。

答案 7 :(得分:14)

非常有经验的开发人员不了解强制转换甚至是面向对象的编程:

我开始帮助完成一个项目,其中一位资深人员遇到了一些过去工作的代码问题而现在却没有。

(班级名称已被更改以保护无辜者,我记不起确切的姓名) 他有一些C ++代码正在侦听传入的消息类并读取它们。它过去的工作方式是传递一个Message类,然后他会在其上插入一个变量,以找出它是什么类型的消息。然后,他将C-style转换为另一个他写的继承自Message的专门类。这个新类具有可以提取数据的功能。现在,这对他来说很好,但现在不是。

经过几个小时看他的代码,他看不出问题,我看了看他的肩膀。我马上告诉他,将C风格的消息传递给派生类并不是一个好主意。他不同意我的观点并说他多年来一直这样做,如果这是错的,那么他所做的一切都是错的,因为他经常使用这种方法。他得到了承包商的进一步支持,他告诉我我错了。他们都认为这总是有效并且代码没有改变所以它不是这种方法,而是其他一些破坏了他的代码的东西。

我看得更远,发现了不同之处。 Message类的最新版本具有虚函数,之前没有使用虚拟。我告诉他们这对他们现在有一个虚拟的桌子和正在查找的功能等等......这导致了他们的问题等等......他们最终达成一致并且我得到了一个评论我永远不会忘记:“虚拟完全搞砸了多态性和面向对象的编程”。

我向他们转发了一个装饰器模式的副本,作为如何向现有类添加一个函数但是没有回复它们的示例。他们如何解决我不知道的想法。

答案 8 :(得分:13)

一个词:宏。我不是说宏在C ++中根本没有位置,但是前C程序员在转换到C ++之后往往会使用它们太多了。

答案 9 :(得分:10)

使用C风格的演员阵容。

C ++允许您独立选择是否允许不相关类型之间的强制转换,以及是否允许更改constvolatile限定符,与C相比,对编译时类型安全性有相当大的改进。还以运行时检查为代价提供完全安全的演员表。

C风格的演员表,几乎任何类型之间的未经检查的转换,允许整个类错误,可以通过更严格的强制转换来轻松识别。如果您想要审核错误转换的错误代码,他们的语法也会使它们很难搜索。

答案 10 :(得分:8)

假设程序员已经犯了试图学习C ++的错误:

  • 不使用STL。
  • 尝试将所有内容都包装在课程中。
  • 尝试使用模板。
  • 不使用Boost。 (我知道Boost可以是一个真正的PITA,也是一个学习曲线,但C ++只是没有它的C + .Boost给C ++一些电池)。
  • 不使用智能指针。
  • 不使用RAII。
  • 过度使用例外。

有争议

  • 转向C ++。不要这样做。
  • 尝试将C stdio转换为iostreams。 Iostreams SUX。不要使用它。它天生就是破碎的。看here
  • 使用libstdc++ library的以下部分:
    • 字符串(除了为我释放它们,去地狱之外)
    • 本地化(这与c ++有什么关系,更糟糕的是,它太可怕了)
    • 输入/输出(64位文件偏移?听说过吗?)
  • 天真地相信你仍然可以在命令行上调试。如果没有代码起重机(IDE),请不要大量使用C ++。
  • 关注C ++博客。 C ++博客关于什么本质上归结为元数据和糖。除了一个很好的常见问题和经验,我还没有看到一个有用的C ++博客。 (请注意,这是一个挑战:我喜欢阅读一个好的C ++博客。)

答案 11 :(得分:8)

using namespace std,因为每个人都做了,然后从不反思它的意思。 或者知道这意味着什么,但是说“std::cout << "Hello World" << std::endl;看起来很难看。”

答案 12 :(得分:8)

使用指针而不是引用传递对象。是的,有时候你需要用C ++指针,但引用更安全,所以你应该尽可能使用它们。

答案 13 :(得分:7)

公开课堂上的所有内容。因此,应该是私有的数据成员不是。

答案 14 :(得分:5)

不完全理解指针和引用的语义以及何时使用其中一个或另一个。与指针相关的还有一个问题,即不能正确管理动态分配的内存,或者无法使用“更智能”的结构(例如智能指针)。

答案 15 :(得分:4)

我最喜欢的是C程序员,他使用多个可选参数编​​写单个方法。

基本上,根据参数的值和/或可为空性,函数会做不同的事情。

答案 16 :(得分:3)

在创建算法和数据结构时不使用模板(example)。它使事情过于局部化或过于通用

即。写作

void qsort(MyStruct *begin, size_t length);  //too localized
void qsort(void *begin, size_t length, 
           size_t rec_size, int(compare*)(void*,void*));  //too generic

而不是

template <class RA_Iter>
void qsort(RA_Iter begin, size_t length);
  //uses RA_Iter::value_type::operator< for comparison

答案 17 :(得分:2)

嗯,糟糕的程序设计超越了语言(强制转换,忽略警告,不必要的预编译魔术,不必要的位错误,不使用char分类宏),而C语言本身并没有创造太多“坏习惯”(Ok) ,宏,特别是从石器时代开始),许多成语直接翻译。但可以考虑一些:

使用一个功能只是因为它在C ++中,所以它必须是正确的做事方式。有些程序不需要继承,MI,异常,RTTI,模板(很好,因为它们......调试负载很陡)或虚拟类的东西。

坚持使用C中的一些代码片段,而不用考虑C ++是否有更好的方法。 (你有一个原因,你现在有class,private,public,const(超出C89扩展),静态类函数,引用。

不熟悉C ++ i / o lib(它的BIG,你需要知道它),以及混合C ++ i / o和C i / o。

答案 18 :(得分:2)

他认为C ++与C语言稍微不同。他将继续编写C语言掩盖的C语言。没有高级使用类,结构被认为不如类,命名空间,新标题,模板强大,不使用这些新元素。他将继续声明没有int的整数变量,他不会提供函数原型。他将使用malloc和free,unsafe指针和预处理器来定义内联函数。这只是一个小清单;)

答案 19 :(得分:1)

结构与类的混淆使用,过度使用将对象指针作为参数的全局方法,以及全局可访问的实例指针,la:

extern Application* g_pApp;
void RunApplication(Application* app, int flags);

另外(不是说这完全没用,但仍然):

const void* buf;

答案 20 :(得分:1)

在函数开头声明所有变量,即使变量仅在100行左右后使用。

尤其适用于在函数内声明的局部变量。

答案 21 :(得分:0)

  1. 解决问题而不是创建基于类的怪物,保证让您享受健康保险和401K福利。

  2. 在单个文件中实现lisp并在其中进行设计。

  3. 编写正常的可读函数而不是覆盖运算符?

  4. 以初级程序员可以理解的风格写作,他们认为良好的做法是“不用C ++编写”。

  5. 用自己的语言与操作系统交谈。

答案 22 :(得分:0)

不能单独留下,而是使用C代替。