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

最近的一个讨论结束了对程序员的坏习惯的嘲笑,他们开始使用另一种语言进行编程时已经暴露在语言之下。 最好的例子是一个Pascal程序员在开始写C时开始#define begin {#define end }

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

告诉大家不要碰到你遇到的事情 。 一个build议,请回答,以尝试达到一种最好的。

对于那些对好习惯感兴趣的人,可以看看这个问题的答案。

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

  • 使用char *而不是std :: string
  • 使用数组而不是std :: vector(或其他容器)
  • 在适当的情况下不使用其他STLalgorithm或库
  • 滥用预处理器常量,types定义或模板会更好
  • 编写SESE风​​格(单入单出口)代码

在函数的顶部声明所有variables,而不是尽可能靠近它们的使用位置。

不使用STL,尤其是std :: string,

和/或

使用std :: strings并在紧密的angular落恢复到旧的Cstring函数。

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

使用指针而不是引用

在头文件中添加using以避免types声明中的std::string这样的名称。

非常有经验的开发人员不理解铸造甚至面向对象编程:

我开始帮助一个项目,其中一个高级人员遇到了一些曾经工作过但现在没有的代码。

(为了保护无辜者,类名已经被改变了,我不记得确切的名字)他有一些C ++代码正在监听传入的消息类并读取它们。 过去的工作方式是通过一个消息类,他将interogatevariables,以找出它是什么types的消息。 然后,他将C风格的消息作为另一个他从Message中inheritance的专门的类。 这个新class级的function就是提取他想要的数据。 现在,这一直很好,但现在不是。

经过好几个小时的查阅,他看不出有什么问题,我看了看他的肩膀。 我马上就告诉他,把C风格的消息传递给派生类是不好的。 他不同意我的看法,说他已经干了好几年了,如果那是错误的,那么他所做的一切都是错误的,因为他经常使用这种方法。 他还得到了一个承包商的支持,他告诉我我错了。 他们都认为,这总是有效的,代码没有改变,所以这不是这个方法,但是破坏了他的代码的其他东西。

我看了一下,发现有所不同。 Message类的最新版本有一个虚函数,以前没有使用过虚函数。 我告诉他们那对现在有一个虚拟的桌子和function正在抬头等等等等,而这正在造成他们的问题,等等……他们最终同意了,我永远不会忘记的评论:“虚拟完全消除了多态性和面向对象的编程”。

我转发他们一个装饰模式的副本作为如何添加一个函数到现有的类的例子,但没有听到他们回来。 他们如何解决我不知道的想法。

一个字:macros。 我不是说macros在C ++中根本就没有地位,但是以前的C程序员在切换到C ++之后倾向于使用它们太多。

使用C风格的演员。

C ++允许你独立地select是否允许在不相关types之间进行转换,以及是否允许改变const volatile限定符,与C相比,编译时安全types的安全性得到了相当大的提高。它还以运行时为代价提供了完全安全的转换检查。

C风格的转换,几乎任何types之间的未经检查的转换,允许整个类别的错误,可以通过更多的限制性转换轻松识别。 他们的语法也使得他们很难search,如果你想审计错误的代码进行可疑的转换。

using namespace std写作,因为每个人都做,然后从不反思其意义。 或者知道它是什么意思,但是说“ std::cout << "Hello World" << std::endl;看起来丑陋”。

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

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

误区

  • 不使用STL。
  • 试图把所有东西都包装在课堂上。
  • 试图使用模板的一切。
  • 不使用Boost。 (我知道Boost可以是一个真正的PITA和一个学习曲线,但是C ++没有它就是C ++,Boost给C ++一些电池)。
  • 不使用智能指针。
  • 不使用RAII。
  • 过度使用例外。

争论的

  • 转移到C ++。 不要这样做。
  • 尝试将C stdio转换为iostreams。 Iostreams SUX。 不要使用它。 这本质上是坏的。 看这里
  • 使用libstdc ++库的以下部分:
    • string(除了为我释放它们,走出去)
    • 本地化(这到底是与c ++有什么关系,更糟糕的是,这很糟糕)
    • input/输出(64位文件偏移?听说过?)
  • 天真地相信你仍然可以在命令行上进行debugging。 如果没有代码起重机(IDE),请不要使用C ++。
  • 继C ++博客。 C ++博客鲤鱼关于什么本质上归结为元数据和糖。 除了一个好的FAQ和经验之外,我还没有看到一个有用的C ++博客。 (注意这是一个挑战:我很想阅读一个好的C ++博客。)

把课堂上的一切都公诸于众。 所以,应该是私人的数据成员不是。

不完全理解指针和引用的语义以及何时使用其中的一个或另一个。 与指针有关的问题也是不正确地pipe理dynamic分配的内存,或者未能使用“智能”构造(例如智能指针)。

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

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

创buildalgorithm和数据结构时不使用模板( 例子 )。 它使事情太局部化或过于通用

即写作

 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 

那么,坏的程序devise超越了语言(强制转换,忽略警告,不必要的预编译器魔法,不必要的位混乱,不使用char分类macros),C语言本身不会产生太多“坏习惯”尤其是石器时代),许多成语直接翻译。 但是可以考虑一些:

仅仅因为它是用C ++来使用一个特性,所以它必须是正确的做法。 一些程序不需要inheritance,MI,exception,RTTI,模板(很好,debugging负载很陡),或者虚拟类的东西。

坚持从C的一些代码片段,而不考虑如果C ++有更好的方法。 (有一个原因,你现在有类,私人,公共,const(扩展超越C89),静态类funcs,引用。

不熟悉C ++ I / O库(它的BIG,你需要知道它),混合C ++ I / O和C I / O。

他认为C ++与C语言只是一种更加不同的语言。他将继续编程被C ++屏蔽的C语言。 没有高级的类的使用,结构被认为比类,名称空间,新的头文件,模板更强大,这些新元素没有被使用。 他将继续声明不带int的整数variables,他不会提供函数原型。 他将使用malloc和free,unsafe指针和预处理器来定义内联函数。 这只是一个小列表;)

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

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

也(不说这是完全无用的,但仍然):

 const void* buf; 

在函数本身的开始声明所有的variables,即使variables只能在100行左右使用。

尤其适用于在函数中声明的局部variables。

单独留下不够好,用C代替。

  1. 解决问题,而不是创build一个基于类的怪物保证让你在健康保险和401K的好处。

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

  3. 编写正常的可读函数而不是重写操作符?

  4. 用一种可以被初级程序员理解为“不用C ++写作”的良好习惯的风格写作。

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