据我所知,如果要在头文件中实现非模板且非内联的内容,而又不违反一次定义规则,唯一的方法就是在匿名命名空间中实现。但我不确定这样类方法实现中的静态变量会发生什么情况:
主要问题包括:
// MyHeader.h
// ... pragma once, defines, etc. ...
// (anonymous namespace removed due to suggestions below)
// namespace
// {
class A // a simplified single-threaded kind of Singleton
{
// ... some private not static data ...
public:
static A& instance()
{
static A instance; // is it guaranteed to be module-global?
return instance;
}
void doNothing();
}
// inline added as suggested in answers below
// actually, I disabled inline in compile settings,
// checked that inlining was not happened using disassembler,
// but `inline` keyword is needed and it matters. Any suggestions, why?
inline void A::doNothing()
{
// it's a very long method, so long that I don't want to
// implement it as inline within class body.
// but not so long to consider refactoring it to smaller functions :)
}
//}
// File executable_part1.cpp
// ... includes, etc. ....
A::instance().doNothing();
// File executable_part2.cpp
// ... includes, etc. ....
A::instance().doNothing();
主要问题包括:
- 是否保证
instance
是模块全局的? - 这是可移植的代码还是行为是编译器实现定义的?
我在Windows上的MSVS 2012上尝试过这个代码。我已经将此头文件包含在3个模块的2个.cpp文件中:一个可执行文件和2个dll,由可执行文件加载。总共6次。
没有名称空间:构造函数被调用了3次,每个“OS级”模块一次。 有名称空间:构造函数被调用了6次,每个cpp文件一次。
更新: 如下所指出,C++'03标准的第7.1.2章解决了我的问题。这里重要的是内联。
inline
关键字。 - juanchopanzainline
关键字。 - juanchopanzainline
,那么instance
将在包括我的头文件在内的所有文件中共享? - Victor Istomininline
到底是什么意思的好回答吗?如果有的话?一旦我们弄清楚它实际上并没有导致或允许内联,那么它的作用是什么?它允许多个定义(即链接器不会抱怨)? {当然,定义必须完全相同}。所有的模板方法都默认为inline
吗? - Aaron McDaid