簡體   English   中英

通過調用C ++中的靜態類函數初始化的全局靜態變量

[英]Global static variable initialised with a call to static class function in c++

不確定如何正確地表達問題,但這是問題所在。

我有一個靜態庫,在其中我有以下課程:

#pragma once
#include <vector>
class A{
public:
 void Run() {
  data_.push_back(10);
  std::cout << "size: " << data_.size() << std::endl;
 }
private:
 static std::vector<int> data_;
};

a.cpp如下:

#include "a.h"
std::vector<int> A::data_;

我在bh還有另一堂課:

#pragma once
#include <string>
class B
{
  public:
    static std::string Get();
};

和b.cpp:

#include "b.h"
#include "a.h"
std::string B::Get()
{
  static A a;
  a.Run();
  return "foo";
}

現在,使用上述靜態庫的主應用程序如下:

#include <iostream>
#include "a.h"
#include "b.h"

static std::string var1= B::Get();

int main(int argc, char** argv)
{
  A a;
  a.Run();
}

試圖了解為什么輸出是:

大小:1

大小:1

整個類的每個靜態數據成員應該有一個實例,因此應該對A :: data_構造函數進行單個調用。 我會遇到“靜態初始化命令慘敗”嗎? 即data_在使用前沒有初始化,但是那我應該崩潰了嗎?

現在,讓我們想象一下我的data_擁有動態初始化的項(沒有POD)。 盡管我插入了2個,但如果data_最后保留了一項,它將如何被破壞?

這就是我的實際代碼中實際發生的事情(有時會在銷毀data_時崩潰)。

擺脫全局靜態( static std :: string var1 = B :: Get(); )可以解決此問題,但是我仍然想了解底層問題。

所描述的情況可以在VS2015中重現(實際情況在gcc 6.2中是可重現的)

我會遇到“靜態初始化命令慘敗”嗎?

最有可能的。

您可以通過函數調用使類的static數據可用,從而消除問題。 例如

class A{
public:
 void Run() {
  getData().push_back(10);
  std::cout << "size: " << getData().size() << std::endl;
 }
private:
 static std::vector<int>& getData();
};

std::vector<int>& A::getData()
{
   static std::vector<int> data;
   return data;
}

當您這樣做時,將在第一次調用A::getData()時初始化data 它完全消除了靜態初始化順序問題。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM