为什么全局定义静态变量被重置?

时间:2016-10-07 14:13:53

标签: c++

我的代码非常大,但我会尽量尽量减少它。

基本上我想定义一个仅在一个地方(我的主要)修改的字符串,然后在我的整个程序中读取。

我的definitions.h包含在任何地方,所以我在那里定义。

  class MyClassVC: UIViewController {

    var html : String?
    var heightBar: CGFloat?
    var webView: UIWebView?

    override func viewDidLoad() {
      super.viewDidLoad()

      heightBar = self.navigationController?.navigationBar.frame.height

      webView = UIWebView(frame: CGRect(x: self.view.frame.origin.x, y: self.view.frame.origin.y, width: self.view.frame.width, height: self.view.frame.height - heightBar!))

      let resources = NSBundle.mainBundle().pathForResource("example", ofType: "html")
      let css = NSURL(fileURLWithPath: resources!)

      webView!.loadHTMLString(html!, baseURL: css)

      setNavBar()

      self.view.addSubview(webView!)
    }

    func close(sender: UIBarButtonItem){
      dismissViewControllerAnimated(true, completion: nil)
    }

    func setNavBar(){
      var title : NSDictionary = Dictionary<NSObject,AnyObject>();
      title = [NSFontAttributeName:UIFont.systemFontOfSize(20), NSForegroundColorAttributeName: UIColor(netHex: AppColors().getAppColors("colors"))]
      self.navigationController!.navigationBar.titleTextAttributes = title as? [String : AnyObject]

      navigationItem.rightBarButtonItem = UIBarButtonItem( title: "Close", style: .Plain, target: self, action: #selector(MyClassVC.close(_:)))
    }
}

在我的主要功能中:

static std::string MAINLOG = "RANDOMNES";

打印出来的文件是

for (int i = 0; i < files.size(); i++){

    // Do stuff       

    prepDbugDir();  // This sets MAINLOG to "CORRECT_VALUE"

    std::cout << "Before " << MAINLOG << std::endl;

    // Call a class function whose includes include my defines.h

    std::cout << "After " << MAINLOG << std::endl;


}

所以我的问题是为什么以及如何在我的课程中保持价值。

4 个答案:

答案 0 :(得分:5)

包含defines.h的每个翻译单元(基本上是.c或.cpp文件)都有自己的变量副本。

我相信在标题

中声明全局extern
extern std::string MAINLOG;

然后将其定义为.c或.cpp文件的任何 one 中的非静态全局变量

std::string MAINLOG = "RANDOMNES";

将解决问题。但它的编码风格很差,IMO。 C ++方式至少是一个单例类。

如果不知道上下文,我不能给出有意义的名字,但这个想法如下:

mainlog.h

class Mainlog {
   Mainlog() = default; // Private default constructor

   static Mainlog& instance();

public:
   static const std::string& get() {
      return instance().value;
   }

   static void set(const std::string& newValue) {
      instance().value = newValue;
   }

private:
   std::string value {"RANDOMNESS"};
};

mainlog.cpp(不要把它放在标题中!)

Mainlog& Mainlog::instance() {
      static Mainlog mainlog;
      return mainlog;
   }

答案 1 :(得分:3)

这是我推荐的内容。

在definitions.h中:

const std::string& mainlog();

在main.cpp中:

const std::string& mainlog() {
  static std::string MAINLOG = "CORRECT_VALUE";
  return MAINLOG;
}

答案 2 :(得分:1)

因为你把它放在你的.cpp文件中包含的define.h文件中,每个.cpp文件都有自己的字符串实例,只能在.cpp文件中看到。 static使变量仅在声明它的.cpp内可见。

在define.h中将static更改为extern,如下所示:

extern std::string MAINLOG;

然后在一个且只有一个.cpp文件中添加:

std :: string MAINLOG =“RANDOMNES”;

这将为您提供您期望的行为,但像这样的全局变量是一个不好的想法。

答案 3 :(得分:0)

在标题中定义带静态存储的变量时,每个转换都会通过该名称获得自己唯一的变量。

如果你不想采用单身方式,一个简单的解决方法是声明

extern const std::string& MAINLOG;
在标题中

,然后主文件定义

std::string MAINLOG_INTERNAL = "RANDOMNESS";
const std::string& MAINLOG = MAINLOG_INTERNAL;

这将为您提供一个可写字符串,该字符串在程序的其余部分中具有只读“视图”。

然后你可以

void prepDbugDir()
{
    MAINLOG_INTERNAL = "CORRECTNESS";
}

在主文件中。