在方法/函数中使用"static const std::string"还是只使用"cons
Is it better to use `static const std::string` or just `const std::string` in a method/function?
我有一个方法/函数:
void foo() {
static const std::string strSQLQuery = "SELECT ... ";
// or maybe
const std::string strSQLQuery = "SELECT ... ";
// some operations on strSQLQuery
// i.e. concatenating with WHERE, etc.:
const std::string strSQL = strSQLQuery + strWHERE;
doSthOnDataBase(strSQL);
}
(SQL只是一个示例)
static const
将仅初始化一次,但会保留在内存中,直到进程结束。- 每次运行
foo()
时都会初始化const
,但当{}
块结束时,内存(堆栈)会释放。
另一方面,字符串"SELECT ... "
仍必须在程序代码中硬编码。而且我们是否使用 1 都没关系。或 2.
那么哪种方法更好呢?使用static const std::string
还是仅使用const std::string
?
或者也许没有一个答案,因为这取决于我想如何使用foo()
- 每秒调用它 1000 次(然后我不想每次都初始化变量)或每月调用它 1000 次(然后我不在乎)。
(我已经阅读了静态常量字符*和常量字符*之间的问题区别,尤其是答案 https://stackoverflow.com/a/2931146/945183,但它们适用于const char*
。
剖析它。很有可能,数据库之旅使字符串的初始化成本相形见绌,以至于无关紧要。
正如已经指出的,局部静态并不是所有编译器上的线程安全的。它们在 GCC 中,C++11 要求它们在 GCC 中,但直到 VS2013 才Microsoft才真正实现这一点。
好吧,如果是一个成员变量,静态 const 是安全的,只要你不故意通过强制转换来破坏 const 部分。 但是从您链接的注释来看,局部变量是不同的:
局部静态变量在第一次遇到其定义时初始化,但在函数退出时不会销毁。因此,它在函数调用之间保持其值。
为了保证安全,gcc 发出锁定来保护初始化,但 MS C++ 不像这里描述的那样,所以这可能是安全的,也可能是不安全的,这取决于编译器,即使被认为是安全的也可能会产生有害的副作用。
这里的权衡似乎是效率与可维护性。 额外的小速度是否值得引入一些微妙的错误。 在研究这个问题时,我现在对我的观点已经完全了解了一圈,我通常会说不。 特别是因为在这种情况下,它是一个简单的字符串初始化,然后是冗长的数据库调用。
众所周知,在您的情况下,"静态"不是必需的。 1) 当您声明并定义一个 const 变量时,编译器有机会将所有出现项替换为您分配的值,如下所示:
const int var = 9;
int b = sqrt( var );
将成为
int b = sqrt( 9 );
这就像 C 样式中的 #define 一样。如果这是您想要的,那么您已经拥有了它,而无需"静态"。
2) 正如其他人所说,即使在 foo() 返回后,静态变量仍将存在。我想这不是你的目标
静态非原始局部变量(无论是否const
)在每次函数调用(初始化标志)上都进行原子读取。它们仅在通过编译器标志特别请求时才是线程安全的(说到 GCC)。在运行时构造的字符串strSQL
比静态初始化引起的原子读取对性能的影响要大得多(因为堆分配)。
最快的是这样的:
void call(std::string const& where) {
static char prefix[] = "SELECT ...";
std::string strSQL;
strSQL.reserve(sizeof(prefix)/sizeof(char) + strWHERE.size());
strSQL.append(prefix, sizeof(prefix)/sizeof(char)).append(strWHERE);
...
}
您是否需要为了速度而牺牲可读性是另一个问题。
- cppcheck在const std::string[]上引发警告
- 将std::string传递给WriteConsole API
- 为std::string的某个索引赋值
- std中有类似find_last_of的函数,而string中没有
- 使用 std::string () const 函数启动线程或未来
- 使用char类型将decimal转换为string,将string转换为decimal
- 迭代和比较映射<字符串、矢量<string>> c++ 中的值
- 当我们进行一些操作时,应该使用什么'std::string'或'std::stringstream'?
- 将向量解析<string>为字符串
- 'string.assign(string.data(), 5)' 是明确定义的还是 UB?
- 如何更改大小(std::string)
- "string.h"在构建适用于iOS的qt应用程序中找不到消息
- C++:如何将 unix 时间的字符串转换为 *tm?(使用时间错误:"cannot convert 'String' to 'tm*' ")
- std::string 的对象真的可以移动吗?
- 与'operator='不匹配(操作数类型'String'且"void")
- SegFault 同时使用 std::string::operator+= 和函数作为参数
- 无法从 std::string 中提取C++ Unicode 符号
- std::string 构造函数如何处理固定大小的 char[]?
- <string> 使用 for 循环写入向量
- 如何检测我何时向可变参数函数传递"std::string"而不是"c_str()"