我有一个方法/功能:
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
只会被初始化一次,但会一直存在,直到进程结束。 const
时都会初始化foo()
,但当{}
块结束时,内存(堆栈)将被释放。另一方面,字符串"SELECT ... "
必须在程序代码中仍然是硬编码的。而且无论我们使用1.还是2。
那么哪种方法更好?使用static const std::string
或仅使用const std::string
?
或者也许没有人回答,因为这取决于我想要使用foo()
- 每秒调用1000次(然后我不想每次都初始化一个变量)或称之为1000次每月(然后我不在乎)。
(我已阅读问题Difference between static const char* and const char*,特别回答https://stackoverflow.com/a/2931146/945183,但它们适用于const char*
。)
答案 0 :(得分:2)
描述它。有可能,数据库的访问使得字符串的初始化成本完全相形见绌无关紧要。
正如已经指出的那样,本地静态在所有编译器上都不是线程安全的。他们在GCC中,而C ++ 11要求他们这样做,但直到VS2013才真正实现了这一点。
答案 1 :(得分:1)
如果是成员变量static const is safe,只要您不通过强制转换有意地击败const部分。但是从链接的注释中,局部变量是不同的:
本地静态变量在第一次遇到其定义时被初始化,但在函数退出时不会被破坏。所以它在函数的调用之间保持其值。
为了保证安全,gcc会发出锁定以保护初始化,但MS C ++没有像here所描述的那样,所以这可以是安全的,也可以不是取决于编译器,即使认为安全可能会产生不良的副作用
这里的权衡似乎是效率与可维护性。这个额外的小速度值得引入一些微妙的错误。在研究这个问题的时候,我现在已经完全看了我的意见,我通常会说没有。特别是因为在这种情况下,它是一个简单的字符串初始化,后跟长时间的数据库调用。
答案 2 :(得分:0)
正如我所知,在您的情况下,“静态”不是必需的。 1)当您声明并定义一个const变量时,编译器有机会用您指定的值替换所有出现的内容,如下所示:
const int var = 9;
int b = sqrt( var );
将成为
int b = sqrt( 9 );
这与C风格的#define一样。如果这是你想要的,那么你已经没有“静态”。
2)正如其他人所说,即使在foo()返回后,静态变量仍然存在。我想这不是你的目标
答案 3 :(得分:0)
静态非原始本地(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);
...
}
是否需要牺牲速度的可读性是另一个问题。