注册 登录  
 加关注
查看详情
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

指南针的天空

你永远也看不到我最寂寞时候的样子,因为只有你不在我身边的时候,我才最寂寞。

 
 
 

日志

 
 

静态成员变量-在头文件中定义--(消除多重定义)__declspec( selectany)  

2010-10-14 13:41:17|  分类: 默认分类 |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

如何消除全局变量或静态类成员变量的多重定义文章出处:http://www.diybl.com/course/3_program/c++/cppjs/20081116/151093.html

      在某些情况下由于某些要求,比如我们可能在多个文件中用到这些变量,我们需要将某些变量或类成员等定义成全局变量或静态成员变量,但这样常常在编译的时候 编译器会报错:变量多重定义,这个问题实在令人头疼,网上大多数解决方案是将全局或类静态变量在.cpp文件中定义,而不是在.h文件中,但这样使用起来 会很麻烦,可能需要自己添加相应的.cpp到工程中.而本文就是介绍在.h文件中定义全局或类静态成员变量.

下面我仅以类静态成员变量为例,说明如何消除头文件中类静态成员变量的多重定义.

//StdAfx.h

// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
//      are changed infrequently
//

#if !defined(AFX_STDAFX_H__ECD81161_3205_499A_8CF2_12BB260538A0__INCLUDED_)
#define AFX_STDAFX_H__ECD81161_3205_499A_8CF2_12BB260538A0__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000

#define WIN32_LEAN_AND_MEAN     // Exclude rarely-used stuff from Windows headers

#include <stdio.h>
#define ONLYDEFINE   //宏定义,关闭多重定义,详情见test.h
#include "test.h"
// TODO: reference additional headers your program requires here

//{{AFX_INSERT_LOCATION}}
// Microsoft Visual C++ will insert additional declarations immediately before the previous line.

#endif // !defined(AFX_STDAFX_H__ECD81161_3205_499A_8CF2_12BB260538A0__INCLUDED_)

//stdafx.cpp

// stdafx.cpp : source file that includes just the standard includes
// test.pch will be the pre-compiled header
// stdafx.obj will contain the pre-compiled type information

#include "stdafx.h"

// TODO: reference any additional headers you need in STDAFX.H
// and not in this file

//test.h

class NoMutiDefine
{
public:
   static int v;
};
#ifdef ONLYDEFINE
__declspec( selectany) int NoMutiDefine::v=5;
#else
int NoMutiDefine::v=5;
#endif

//test.cpp

// test.cpp : Defines the entry point for the console application.
//

#include "stdafx.h"

int main(int argc, char* argv[])
{
    printf("%d\n",NoMutiDefine::v);
    return 0;
}

运行结果:

5
Press any key to continue

假设我们将#define ONLYDEFINE 注释掉,编译器就会报错:

Compiling...
test.cpp
Linking...
test.obj : error LNK2005: "public: static int NoMutiDefine::v" (?v@NoMutiDefine@@2HA) already defined in StdAfx.obj
Debug/test.exe : fatal error LNK1169: one or more multiply defined symbols found
执行 link.exe 时出错.

///////////////////////////

对__declspec( selectany )的介绍

msdn上是这么解释的:

Microsoft Specific

Tells the compiler that the declared global data item (variable or object) is a pick-any COMDAT (a packaged function).
__declspec( selectany ) declarator
Remarks

At link time, if multiple definitions of a COMDAT are seen, the linker picks one and discards the rest. If the linker option /OPT:REF (Optimizations) is selected, then COMDAT elimination will occur to remove all the unreferenced data items in the linker output.

Constructors and assignment by global function or static methods in the declaration do not create a reference and will not prevent /OPT:REF elimination. Side effects from such code should not be depended on when no other references to the data exist.

For dynamically initialized, global objects, selectany will discard an unreferenced object's initialization code, as well.

A global data item can normally be initialized only once in an EXE or DLL project. selectany can be used in initializing global data defined by headers, when the same header appears in more than one source file. selectany is available in both the C and C++ compilers.


Note:
selectany can only be applied to the actual initialization of global data items that are externally visible.

  评论这张
 
阅读(1129)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2018