我是一名Java开发人员,我对C++很陌生.我需要实现某种实用类,我正在考虑将这些方法实现为static.但是,我遇到了关于命名空间函数与静态方法的stackoverflow问题,并且显然名称空间函数是首选方法.所以我想知道如果有关于如何实现命名空间功能的任何文章或示例.例如,我应该如何在头文件中声明命名空间函数?头文件是否只包含类头文件等函数定义,实现应该在cpp文件中,还是我应该直接在头文件中实现函数?
基本上,我试图实现一个应用程序来解析包含一些命令的文本文件.所以我正在考虑实现静态辅助方法来处理文本处理.例如readCommand(字符串行).如果我的方向错误,请告诉我.谢谢
jus*_*tin 26
我应该如何在头文件中声明命名空间函数?
namespace MON {
// extern:
t_ret func(const t_param& pValue);
// 'inline':
inline t_ret inline_func(const t_param& pValue) { ... }
} // << MON
Run Code Online (Sandbox Code Playgroud)
头文件是否只包含类头文件等函数定义,实现应该在cpp文件中,还是我应该直接在头文件中实现函数?
这取决于您是否希望它们(可能)内联或导出.这通常归结为最小化依赖性.
扩展出口或内联:
你经常喜欢extern函数来减少c ++中的依赖.这相当于在类方法中将定义与声明分开:
file.hpp
namespace MON {
// extern:
t_ret func(const t_param& pValue);
} // << MON
Run Code Online (Sandbox Code Playgroud)
file.cpp
#include "hefty_stuff.hpp"
MON::t_ret MON::func(const t_param& pValue) { ... }
Run Code Online (Sandbox Code Playgroud)
然而,有时候定义在某些情况下是可见的,通常是为了表现,或者当你知道尺寸很重要并且标题不包含在很多地方时,它有时是至关重要的.因此,inline变体也是一种选择.
内联函数仍然可以被导出,并且可以按要求内联 - 但是,任何内联函数副本都可以合并(具体而言,实现可以自由地假设所有定义都相同,并且函数的任何副本都是不必要的).
使用导出的定义,您可以选择性地限制(或隔离)您的包含依赖项.也就是说,#include "hefty_stuff.hpp"不必在标题中使用函数file.hpp.
基本上,我试图实现一个应用程序来解析包含一些命令的文本文件.所以我正在考虑实现静态辅助方法来处理文本处理.
好吧,static应该避免在这里.c ++使用one-definition-rule.static只会导致许多不必要的副本.此外,匿名命名空间是c static函数的c ++方法:
namespace {
t_ret func(const t_param& pValue) { ... }
} // << anon
Run Code Online (Sandbox Code Playgroud)
注意:匿名命名空间也可能导致不必要的副本.你会用它们作为一个静态函数的替代品的原因是,如果你想要或需要从一个定义规则偏离,而不愿申报符号可以"解决"一个范围.
最后一点是关于template<>声明.使用模板,定义必须在使用的位置可见,除非您的编译器支持extern模板.对于模板,您可以通过多种方式完成定义可见性.通常,人们只需简单地声明定义,或为定义添加标题,该标题包含在标题的末尾或根据需要.使用模板,不需要声明函数inline以避免多个定义错误.
jua*_*nza 17
您可以在标题中声明函数:
namespace A {
void foo();
}
Run Code Online (Sandbox Code Playgroud)
并在.cpp中实现:
namespace A {
void foo() { std::cout << "foo!"; }
}
Run Code Online (Sandbox Code Playgroud)
您还可以将实现放在标头中,确保声明它inline以避免违反一个定义规则:
namespace A {
inline void foo() { std::cout << "foo()!"; }
}
Run Code Online (Sandbox Code Playgroud)
请注意,将实现放在标头中意味着客户端代码对实现具有编译依赖性,以及用于实现的标头.在上面的示例中,客户端代码现在依赖于标头,如果我们做一些微不足道的事情,比如在打印输出中添加感叹号,我们需要重新编译,而不是重新链接所有客户端代码.
将模板函数的实现放在头部或头部包含的文件中是非常重要的,这些不能放在.cpp中:
namespace B {
template <class T>
inline void foo(const T& t) { std::cout << t.name() << "\n"; }
}
Run Code Online (Sandbox Code Playgroud)