不要在头文件中定义有链接的实体
[来源] 达内 [编辑] 达内 [时间]2012-09-11
具有链接的实体,包括名字空间级的变量或函数,都需要分配内存,在头文件中定义这样的实体将导致连接错误或者内存浪费。所以,应该将所有具有链接的实体放入实现文件
具有链接的实体,包括名字空间级的变量或函数,都需要分配内存,在头文件中定义这样的实体将导致连接错误或者内存浪费。所以,应该将所有具有链接的实体放入实现文件。
< p style="margin: 5px auto; padding: 0px; text-indent: 0px; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 22px; orphans: 2; text-align: left; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "> 下面的头文件:
< div style="margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); font-family: 'Courier New'; font-size: 12px; border: 1px solid rgb(204, 204, 204); overflow: auto; color: rgb(0, 0, 0); font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; " class="cnblogs_code">
1
int max;
2 string
hello("Hello, world!
");
3 void fun() { ... }
< p style="margin: 5px auto; padding: 0px; text-indent: 0px; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 22px; orphans: 2; text-align: left; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "> 只要被一个以上的源文件所包含,就很容易导致链接错误,编译器会报告存在重复符合错误。原因很简单:每个源文件中,都会定义max、hello和fun的函数体,并分配空间。当进行链接的时候,链接器将面对多个具有相同名字而且互相在竞争的符号。< p style="margin: 5px auto; padding: 0px; text-indent: 0px; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 22px; orphans: 2; text-align: left; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "> 解决之道非常简单
——
只在头文件中放置声明即可:
< div style="margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); font-family: 'Courier New'; font-size: 12px; border: 1px solid rgb(204, 204, 204); overflow: auto; color: rgb(0, 0, 0); font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; " class="cnblogs_code">
1
extern max;
2 extern
string hello;
3 void fun();
< p style="margin: 5px auto; padding: 0px; text-indent: 0px; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 22px; orphans: 2; text-align: left; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "> 而实际的定义则放在一个实现文件中。
< p style="margin: 5px auto; padding: 0px; text-indent: 0px; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 22px; orphans: 2; text-align: left; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "> 同样,不要在同文件中定义名字空间级的static实体,例如:
< div style="margin: 5px 0px; padding: 5px; background-color: rgb(245, 245, 245); font-family: 'Courier New'; font-size: 12px; border: 1px solid rgb(204, 204, 204); overflow: auto; color: rgb(0, 0, 0); font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; orphans: 2; text-align: left; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; " class="cnblogs_code">
1
static int
max; 2
static string
hello("Hello, world!
");
3 static
void fun() { ... }
< p style="margin: 5px auto; padding: 0px; text-indent: 0px; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 22px; orphans: 2; text-align: left; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; "> 这种对static的错误使用比在头文件中只定义全局实体还要危险。对于全局实体,至少链接器可能会立即发现重复,但是静态数据和函数的重复是合法的。因此,若在某个头文件中定义了静态数据和静态函数,而该头文件要被50个文件包含,那么函数体和数据所占用的空间在最终的可执行文件中会重复50次,造成内存浪费。< p style="margin: 5px auto; padding: 0px; text-indent: 0px; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 22px; orphans: 2; text-align: left; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; ">
例外情况:
< p style="margin: 5px auto; padding: 0px; text-indent: 0px; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 22px; orphans: 2; text-align: left; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; ">(1)内联函数。
< p style="margin: 5px auto; padding: 0px; text-indent: 0px; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 22px; orphans: 2; text-align: left; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; ">(2)函数模版。
< p style="margin: 5px auto; padding: 0px; text-indent: 0px; color: rgb(0, 0, 0); font-family: verdana, 'ms song', 宋体, Arial, 微软雅黑, Helvetica, sans-serif; font-size: 14px; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: 22px; orphans: 2; text-align: left; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px; ">(3)类模板的静态数据成员。