是否可以实现仅表头的非模板类
Is it possible to implement header-only non-template class?
就我的理解标准而言,在不违反One Definition Rule的情况下,在头中实现非模板和非内联的东西的唯一方法是实现匿名命名空间。
但我不确定在这样的类方法实现中静态变量会发生什么:
// 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文件中:一个可执行文件和两个由可执行文件加载的dll。总共6次。
没有命名空间:constructor被调用了3次,每个"操作系统级别"模块调用一次。使用namespace:cconstuctor被调用了6次,每个cpp文件调用一次。
更新:如下所述,C++’03标准的第7.1.2章解决了我的问题。内联在这里很重要。
您不应该使用未命名的命名空间,因为每个翻译单元都有自己的结构A。
只做
class A
{
// ... some private not static data ...
public:
static A& instance()
{
static A instance;
return instance;
}
void doNothing();
};
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 :)
}
- exe/dll之间不共享singleton是正常的
- 有了未命名的命名空间,每个TU都有singleton,而没有它,整个exe(和分别为整个Dll)都共享singleton
对于您的配置:1个exe和2个cpp,2个Dll和两个cpp:你的实验是正确的:6个有未命名的命名空间,3个没有。
我真的不太理解这个问题(也许我错过了什么),所以保留你需要的。
据我所知,静态方法和数据属于类本身,而不属于类的实例。因此,静态数据只存在一次,如果从不同的对象访问这些数据,则它们独立地是相同的。静态方法类似于普通的外部函数,它们没有可用的this
指针。属于类的命名空间,因此每个类都可以实现具有相同名称的静态函数,并且不会因为它们的名称不相等而发生名称冲突,因为完全限定名称是:"classOfApparttence::nameOfFunction",并且每个类的完全限定名称不同。本质上,如果您没有为类实现任何对象,那么该类就只是一个命名空间。
相关文章:
- 如果没有malloc,链表实现将失败
- 如何在c++中实现处理器调度模拟器
- 如何在c++中使用引用实现类似python的行为
- 实现无开销push_back的最佳方法是什么
- 使用简单类型列表实现的指数编译时间.为什么
- 如何在BST的这个简单递归实现中消除警告
- 实现一个在集合上迭代的模板函数
- 我应该实现右值推送功能吗?我应该使用std::move吗
- 如何正确实现和访问运算符的各种自定义枚举器
- C++Union/Struct位域的实现和可移植性
- 这个极客对极客的trie实现是否存在内存泄漏问题
- 在c++中实现LinkedList时,应出现未处理的错误
- 为左值和右值的包装器实现C++范围
- 使用模板进行堆栈实现; "name followed by :: must be a class or namespace"
- 使用GSoap实现ONVIF
- 在用于格式4的arm模拟器中实现功能时的一个问题
- 用于AVX的ln(x)的实现,m256
- 用常见虚拟函数实现的任意组合来实现派生类的正确方法是什么
- 在C++中,如何在类和函数(可能是模板化的)的头中编写完整的实现
- 是否可以实现仅表头的非模板类