最近的讨论结束时嘲笑程序员的坏习惯,当他们开始用另一种语言编程时,他们太暴露于某种语言。最好的例子是Pascal程序员在开始编写C时开始#define begin {
和#define end }
。
目标是在开始使用C ++时尝试捕捉C程序员的坏习惯。
告诉您遇到的大不。请回答一个建议,试图实现一种最好的。
对于那些对良好习惯感兴趣的人,请查看对此question的接受答案。
答案 0 :(得分:51)
使用原始指针和资源而不是RAII对象。
答案 1 :(得分:38)
答案 2 :(得分:30)
声明函数顶部的所有变量,而不是尽可能接近它们的位置。
答案 3 :(得分:18)
不使用STL,特别是std :: string,
和/或
使用std :: strings并在紧急角落恢复旧c字符串函数。
答案 4 :(得分:18)
答案 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 ++允许您独立选择是否允许不相关类型之间的强制转换,以及是否允许更改const
和volatile
限定符,与C相比,对编译时类型安全性有相当大的改进。还以运行时检查为代价提供完全安全的演员表。
C风格的演员表,几乎任何类型之间的未经检查的转换,允许整个类错误,可以通过更严格的强制转换来轻松识别。如果您想要审核错误转换的错误代码,他们的语法也会使它们很难搜索。
答案 10 :(得分:8)
假设程序员已经犯了试图学习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)
解决问题而不是创建基于类的怪物,保证让您享受健康保险和401K福利。
在单个文件中实现lisp并在其中进行设计。
编写正常的可读函数而不是覆盖运算符?
以初级程序员可以理解的风格写作,他们认为良好的做法是“不用C ++编写”。
用自己的语言与操作系统交谈。
答案 22 :(得分:0)
不能单独留下,而是使用C代替。