在方法/函数中使用`static const std :: string`或只是`const std :: string`更好吗?

时间:2014-01-24 10:16:38

标签: c++ string static

我有一个方法/功能:

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只是一个例子)

  1. static const只会被初始化一次,但会一直存在,直到进程结束。
  2. 每次运行const时都会初始化
  3. foo(),但当{}块结束时,内存(堆栈)将被释放。
  4. 另一方面,字符串"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*。)

4 个答案:

答案 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);
    ...
}

是否需要牺牲速度的可读性是另一个问题。