在C ++中,你几乎一直都在做什么?

时间:2008-11-25 00:30:41

标签: c++

当我在C ++中将课程放在一起时,我几乎总是会做一些事情。

1)虚拟析构函数 2)复制构造函数和赋值运算符(我根据名为Copy()的私有函数实现它们,或者将它们声明为私有,因此明确禁止编译器自动生成它们。)

你发现什么东西几乎总是有用的?

10 个答案:

答案 0 :(得分:14)

奇怪的是,这里的大部分建议都是我特别不做的事情。

  • 除非我专门设计继承,否则我不会将dtors设为虚拟。它增加了很多开销并且阻止了自动内联,这很糟糕,因为大多数dtors都是空的(并且很少有类受益于继承)。
  • 我不会复制ctor / assignment op,除非默认设置不起作用 - 如果不能,我可能想重新考虑设计。请记住,在字符串和&之间矢量,几乎没有理由再打电话给新人了。创建与默认版本相同的副本,几乎肯定会降低效率。
  • 我不添加字符串强制转换。它会引起太多问题,在这些问题中,无意中调用了强制转换。最好添加一个ToString()方法。
  • 我没有添加朋友oper<<,因为朋友是邪恶和凌乱的。最好添加一个Display(ostream)方法。然后oper<<可以打电话给那个,而不需要成为朋友。事实上,你可以使oper<<调用Display()的模板函数,再也不用担心了。

答案 1 :(得分:10)

我发现打开gcc标志-Wall-Werror,并且(这很有趣)-Weffc++有助于捕捉许多潜在问题。从gcc手册页:

  -Weffc++ (C++ only)
      Warn about violations of the following style guidelines from Scott
      Meyers’ Effective C++ book:

      ·   Item 11:  Define a copy constructor and an assignment operator
          for classes with dynamically allocated memory.

      ·   Item 12:  Prefer initialization to assignment in constructors.

      ·   Item 14:  Make destructors virtual in base classes.

      ·   Item 15:  Have "operator=" return a reference to *this.

      ·   Item 23:  Don’t try to return a reference when you must return
          an object.

      and about violations of the following style guidelines from Scott
      Meyers’ More Effective C++ book:

      ·   Item 6:  Distinguish between prefix and postfix forms of incre-
          ment and decrement operators.

      ·   Item 7:  Never overload "&&", "││", or ",".

      If you use this option, you should be aware that the standard
      library headers do not obey all of these guidelines; you can use
      grep -v to filter out those warnings.

答案 2 :(得分:4)

当我把一个课程放在一起时,我做的第一件事就是在它上面写一些关于为什么它存在以及它做什么的doxygen评论。

我曾经在一个小组项目上工作,他们说他们想在项目结束时记录这些东西。稍后将注释放入代码中就太乱了。我不想再发生这种情况。

答案 3 :(得分:3)

在类定义后添加分号。每次我忘记这样做时,这会不断地让我陷入困境,因为gcc的错误信息含糊不清,而且它通常会说像“这样的东西不能在函数的返回类型中定义类型”这意味着很多......

答案 4 :(得分:3)

停下来思考

答案 5 :(得分:2)

通常,

operator string () const;

friend ostream& operator << (ostream&, const MyClass&);

答案 6 :(得分:1)

在头文件中,执行

#ifndef __SOMEDEFINE__
#define __SOMEDEFINE__

#endif

在VS中,我添加

#pragma warning(disable: 4786)

哦,我也用

#include <inttypes.h>

因为我&lt; 3 C99类型。

答案 7 :(得分:1)

通常包含一个返回代码枚举,因此该类可以告诉其调用者其成员函数中发生了什么。通常,这将是该类所有成员返回的唯一类型。所有结果都通过引用传回。

答案 8 :(得分:1)

我首先调用设置包含保护的开发环境宏(#ifdefs和/或#pragma一次)。

接下来,我将列出类名及其所在的任何名称空间,而不添加任何功能。

然后我为该类创建单元测试文件,并添加第一个测试(通常是参数构造函数测试)。

我只是在那里工作,编写和重构课程,因为我想到了我真正需要的东西。我倾向于专门测试的东西:const-correctness,隐式和显式转换,抛出的异常类型等等。

答案 9 :(得分:1)

我用一个全新的类文件做的第一件事就是写几段注释,关于类的作用,它存在的原因,它使用的类以及如何使用它。在模块中随机打开文件的人应该足够了解该注释以找到他们实际要查找的文件。

我同意James的观点 - 我非常小心不要将功能添加到不需要它的类中,大多数类不需要虚拟析构函数(或根本不需要析构函数)。如果他们这样做,我怀疑为什么他们不只是使用智能指针和其他自动内存管理。显然有许多类(即智能范围锁)需要一个析构函数,但它不仅仅是理所当然的。