不要在头文件中定义有链接的实体

具有链接的实体,包括名字空间级的变量或函数,都需要分配内存,在头文件中定义这样的实体将导致连接错误或者内存浪费。所以,应该将所有具有链接的实体放入实现文件。

  下面的头文件:

1 int max;
2 string hello("Hello, world!");
3 void fun() { ... }

  只要被一个以上的源文件所包含,就很容易导致链接错误,编译器会报告存在重复符合错误。原因很简单:每个源文件中,都会定义max、hello和fun的函数体,并分配空间。当进行链接的时候,链接器将面对多个具有相同名字而且互相在竞争的符号。

  解决之道非常简单——只在头文件中放置声明即可:

1 extern max;
2 extern string hello;
3 void fun();

  而实际的定义则放在一个实现文件中。

  同样,不要在同文件中定义名字空间级的static实体,例如:

1 static int max;
2 static string hello("Hello, world!");
3 static void fun() { ... }

  这种对static的错误使用比在头文件中只定义全局实体还要危险。对于全局实体,至少链接器可能会立即发现重复,但是静态数据和函数的重复是合法的。因此,若在某个头文件中定义了静态数据和静态函数,而该头文件要被50个文件包含,那么函数体和数据所占用的空间在最终的可执行文件中会重复50次,造成内存浪费。博文来源http://7m56.com/bocaixinwen/2012091088.html

例外情况:

(1)内联函数。

(2)函数模版。

(3)类模板的静态数据成员。

相关文章
相关标签/搜索