C++ 在方法/函数中使用'static const std::string'还是只使用'const std::string'更好?

C++ 在方法/函数中使用'static const std::string'还是只使用'const std::string'更好?,c++,string,static,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

我有一个方法/功能:

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

静态常量将只初始化一次,但在进程结束之前会一直保存在内存中。 每次运行foo时都会初始化const,但是{}块结束时会释放内存堆栈。 另一方面,字符串选择。。。必须仍然在程序代码中硬编码。如果我们用1也没关系。或2

那么哪种方法更好呢?使用静态常量std::string还是仅使用常量std::string

或者可能没有人回答,因为这取决于我想如何使用foo-每秒调用1000次,那么我不想每次初始化变量,或者每月调用1000次,那么我不在乎


我读过问题,特别是答案,但它们适用于常量char*

如果是成员变量,只要您不是故意通过强制转换来击败常量部分。但从您的链接注释来看,局部变量是不同的:

局部静态变量在第一次遇到其定义时被初始化,但在函数退出时不会被销毁。因此,它在函数调用之间保持其值

为了保证安全,GCC发出锁定来保护初始化,但是MSC++没有描述,所以这取决于编译器,或者是安全的,即使假设安全的也会产生有害的副作用。


这里的权衡似乎是效率与可维护性。这一额外的微小速度是否值得引入一些细微错误的可能性。在研究这一点的时候,我现在完全同意我的观点,我通常会说不。特别是在这种情况下,这是一个简单的字符串初始化,然后是一个长时间的数据库调用。

正如我所知,静态在您的情况下是不必要的。 1当您声明和定义常量变量时,编译器有机会用您指定的值替换所有实例,如下所示:

const int var = 9;
int b = sqrt( var );
将成为

int b = sqrt( 9 );
其行为与C样式中的定义类似。如果这是您想要的,那么您已经拥有了它,而没有静电干扰


2正如其他人所说,即使在foo返回之后,静态变量仍然存在。我想这不是你的目标。很有可能,访问数据库的过程会使字符串的初始化成本相形见绌,这无关紧要


正如已经指出的,局部静态在所有编译器上都不是线程安全的。它们在GCC中,C++11要求它们在GCC中,但Microsoft直到VS2013才真正实现了这一点。

静态非原语局部变量在每个函数调用初始化标志上是否执行原子读取。仅当通过编译器标志进行特定请求时,它们才是线程安全的。由于堆分配的原因,在运行时构造的字符串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);
    ...
}

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

您似乎已经概述了每种解决方案的优缺点。提示:没有比这更好的了。请注意,当你有这样一个静态文件时,你的程序会锁定。我会选择静态常量,因为它需要更少的内存堆栈,这是一个非常昂贵的浪费,基本上也有相同的效果。作为旁注,在通常全局定义为结构成员的方法中使用const define是非常罕见的…@Pandrei:wat。静态字符串表示如果在多线程上下文中使用,代码将爆炸。非静态线程意味着几个字节放在堆栈上,其余的放在堆上。我不知道你在说什么。堆栈内存浪费昂贵。您可以使用const char*const strSQLQuery=SELECT。string是动态初始化和用户定义的。幸运的是找到了一个编译器在上面进行不断的传播。直到VS2013,微软才正确地实现了一些C++11。他们还不太清楚…我知道,韦特姆的答案和这个很相似,但是塞巴斯蒂安,更切题了,伊姆霍,没有重复我在问题中的想法。