成员静态函数

时间:2016-05-12 04:40:59

标签: c++ boost static

总的来说,我想问一下会员静态函数的局部变量存储在哪里?如果在静态函数中使用静态变量,那么变量只会初始化一次吗?

请参阅以下代码

std::string const CONST1 = "const1";
std::string const CONST2 = "const2";
std::string const CONST3 = "const3";

class Test
{
  public:
    static const std::vector<std::string> GetSomeMap();
}

const std::vector<std::string> Test::GetSomeMap()
{
  static std::vector<std::string> SomeMap = boost::assign::list_of(CONST1)(CONST2)(CONST3);

 return SomeMap;

}

从上面的代码中,将SomeMap声明为静态是否有优势?(我希望它只被初始化一次)

4 个答案:

答案 0 :(得分:3)

  

如果在静态函数中使用静态变量,该变量只会初始化一次吗?

答案是&#34;是&#34;。
它也是&#34;是&#34;对于static常规变量,即非static成员函数 它也是&#34;是&#34;对于非成员函数的static个变量。

答案 1 :(得分:0)

函数内部的静态变量(无论函数类型如何)都是stored in the "DATA" segment,就像global variables一样。所以你可以这么说,函数静态变量类似于全局变量,只是它们只能在有限的范围内(函数体)通过名称访问。

答案 2 :(得分:0)

如果变量是静态的,则存储在堆中。 如果变量是静态函数的成员,则它存储在静态局部变量中。 并且,它们只被初始化一次。

答案 3 :(得分:0)

  

总的来说,我想问一下会员静态函数的局部变量存储在哪里?

取决于。静态常量普通旧数据类型可以存储在只读数据段中。具有常量初始化器的静态变量可以存储在数据段中,并且需要动态初始化的静态变量可以存储在BSS段中。

  

如果在静态函数中使用静态变量,该变量只会初始化一次吗?

是。在这种情况下,SomeMap将在控件第一次通过其声明时初始化。

  

具有静态存储持续时间(3.7.1)的所有本地对象的零初始化(8.5)在任何之前执行   进行其他初始化。 POD类型(3.9)的本地对象,其静态存储持续时间初始化为   在第一次输入块之前初始化常量表达式。允许执行   在与a相同的条件下,以静态存储持续时间早期初始化其他本地对象   允许实现在命名空间范围内静态初始化具有静态存储持续时间的对象   (3.6.2)。否则,在第一次控制通过其声明时初始化这样的对象;这样的   对象在初始化完成后被视为初始化。如果初始化通过抛出退出   例外,初始化未完成,因此下次控制进入时将再次尝试   声明。

ISO / IEC 14882:2003(E)第6.7节第4段(抱歉,我没有最新的标准版本)

  

从上面的代码中,将SomeMap声明为静态是否有优势?(我希望它只被初始化一次)

是的,将它声明为静态是有好处的 - 它只会初始化一次,只有在使用时才会初始化。如果永远不调用Test :: GetSomeMap,那么SomeMap永远不会被初始化。

正如上面的@Blacktempel所述,Test :: GetSomeMap应该通过引用返回,以消除对创建额外副本SomeMap的任何疑问。

您还应注意,您要承担创建三个字符串(CONST1,CONST2和CONST3)的成本,每个字符串可以分配堆内存来存储其常量表达式字符串初始值设定项的副本(& #34; const1&#34;,&#34; const2&#34;,&#34; const3&#34;)。此外,如果调用Test :: GetSomeMap,则还会产生初始化SomeMap向量的成本,该向量也可能会分配堆内存来存储字符串的副本。

如果您担心内存使用和初始化开销,并且您真的想要一个静态常量字符串数组,只需声明一个,如下所示:

   static const char* const * GetSomeMap(void) {
    static const char* const SomeMap[] = {"const1", "const2", "const3"};
    return SomeMap;
}

SomeMap将占用最少的内存而没有初始化开销(并且完全不可更改)。