2016-09-15 18 views
0

我正在阅读一堆来自XML文件的应用程序的“设置”,我希望这些设置驻留在所有我可以访问的函数的命名空间中。我通过在标头中声明命名空间变量为'extern int test'成功完成了这项工作。然后在源文件'int test {0};'中初始化它们。然后在源文件中有一个函数,它读取XML并将值赋给名称空间变量,并且所有内容都是hunky dory。如何使用函数中的值初始化名称空间中的全局常量变量?

问题是我意识到当他们只需要保持不变时,我正在创建~100个可读写全局变量。所以我试图改变我的代码,现在他们是不变的,我不明白这是可能的。下面是我的尝试:

//settings.hpp 
#pragma once 
//header guard 

namespace settings { 
    extern const int ktest; 
} 

//settings.cpp 
void ReadXML() { 
    int testvalue{1}; //1 is default values 

    //here would be some code that gets value form XML and assigns it to testvalue 

    namespace settings { 
     const int ktest{testvalue}; 
    } 
} 

现在的问题是我不能把里面的函数的命名空间值。因此,如果我将它们移到函数ReadXML之外,我也必须移动临时变量,但即使这样也没关系,因为我只需要在函数执行后初始化命名空间变量。我正在努力做甚么?

回答

0

好吧,我不确定这是雨滴是怎么回事,但它激励我找到这个解决方案。这里是我的结构:

//xmlreader.hpp 
#pragma once 
//header guard 

int ReadXML(); 

namespace settings { 
    extern const int kreadsucces; //Has to be first, is result of read function 
    extern const int ktest; 
} 

//xmlreader.cpp 
#include "xmlreader.hpp" 
static int test {0};   //Default in case of exception in read function 

int ReadXML() { 
    //xml read code here, assign new 'test' value if successful 
    test = 2; 
    return 1; 
} 

namespace settings { 
    const int kreadsucces{ReadXML()}; //ReadXML is executed before main now! 
    const int ktest{test}; 
} 

//main.cpp 
#include "xmlreader.hpp" 
// if (ReadXML() > 0) {}    //Was old code, now called at initialization 
if (settings::kreadsuccess > 0) { 
    std::cout << "XML read succesful" << std::endl; 
} else { 
    std::cout << "XML read failed, using defaults" << std::endl; 
} 
std::cout << settings::ktest << std::endl; //Prints 2 

我所做的是添加了“设置:: readsuccess”变量,并与我的函数初始化它,而不是在我的主要的开始调用它。现在,这个函数实际上在程序启动前立即运行,甚至在主要启动之前也分配了所有这些占位符变量,所以当其他变量初始化时,函数已经运行。

现在我承认,我所做的似乎有点快捷,但它的工作原理,现在我有一个命名空间,充满了100个全局常量变量,在运行时初始化,可通过包含标题文件。这是合法的,还是更好的说,这是一个比只有100个可变全局变量更好的做法吗?

+0

我想说问题不在于你是否有可变或常量的全局变量。我会说这个问题是全局变量。其中100个。这不是很好的编程习惯。 –

+0

我没有争辩,但如果你有100个全局变量,如果它们不变,它会不会更好?这种改变并不需要我去改变每一个源文件,但至少让它们保持不变,我认为这会有所改进。 – DrTarr

-1

为了设置一个常量的全局变量,需要在定义它时进行设置。所以这样做:

const int ktest = getValueofKtest(); 

此外,设置一百个变量是一个维护的噩梦。使用设置类。

+0

是的,我刚刚阅读[this](http://stackoverflow.com/questions/26072216/c-global-extern-constant-defined-at-runtime-available-across-multiple-source-f)post和在那里也提出了返回功能。像你用return函数说过的问题是我必须为每个变量写一个函数,这意味着我必须打开,读取和关闭xml 100次。效率不高。也许我会创建一个单例类,并通过引用我的所有线程来传递它。仍然比使用命名空间更麻烦,但我会避免可变的全局变量? – DrTarr

+0

每个变量的函数并不意味着您必须读取每个变量的xml。 –

0

在头文件中声明一个函数原型,然后声明你的命名空间,并根据其返回值使extern常量初始化。然后定义你的主要功能:

//header.hpp 
#pragma once 

int RetValue(); // prototype 

namespace A{ 
    extern const int value(RetValue()); 
} 


//source.cpp 

int RetValue(){return 7;} // defining retValue 

int main() 
{ 
    cout << A::value << endl; // output: 7 
} 
+0

我不明白这在实践中如何与Anon的建议不同。我仍然需要为每个单独的变量创建一个RetValue,除了这里,我将初始化放在头文件中而不是源文件中。除了清晰(可辩论)代码之外,是否还有其他好处,因为我不必在源文件中初始化命名空间变量? (相反,我不得不把函数原型放在头文件中)。 – DrTarr