2016-09-15 2 views
0

XML 파일에서 응용 프로그램에 대한 여러 '설정'을 읽는 중입니다.이 설정이 모든 내 기능에 액세스 할 수 있도록 네임 스페이스에 있어야합니다. 나는 헤더에서 네임 스페이스 변수를 'extern int test;라고 선언하여이 작업을 성공적으로 수행했습니다. 그런 다음 소스 파일 'int test {0};'에서 초기화하십시오. 그런 다음 소스 파일에는 XML을 읽고 네임 스페이스 변수에 값을 할당하는 함수가 있으며 모든 것이 늠름한 것입니다.네임 스페이스의 전역 const 변수를 함수의 값으로 초기화하는 방법은 무엇입니까?

문제 그들은 상수 일 필요가있을 때 ~ 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

나는 전역 변수가 가변적인지 const인지 여부는 문제가 아니라고 말할 것이다. 문제는 글로벌 변수라고 말할 수 있습니다. 그리고 100 명. 그건 좋은 프로그래밍 실습이 아닙니다. –

+0

나는 그것을 주장하지 않는다. 그러나 만일 당신이 100 개의 전역 변수를 가지면, 그들이 일정하다면 더 좋지 않을까? 이 변경 사항은 모든 단일 소스 파일을 변경해야하지만 적어도 일정하게 만들 필요는 없었습니다. 개선이 될 것이라고 생각했습니다. – DrTarr

-1

상수 전역 변수를 설정하려면 변수가 정의 될 때 설정해야합니다. 이렇게하십시오 :

const int ktest = getValueofKtest(); 

또한, 100 개의 변수를 설정하는 것은 유지 보수의 악몽입니다. 설정 클래스를 사용하십시오.

+0

예, 방금 [this] (http://stackoverflow.com/questions/26072216/c-global-extern-constant-defined-at-runtime-available-across-multiple-source-f) 게시물을 읽었습니다. 반환 함수도 제안되었습니다. 당신이 리턴 함수로 말한 것과 같은 문제는 각 변수에 대해 함수를 작성해야만합니다. 그러면 xml을 열고 읽으며 닫아야한다는 것을 의미합니다. 별로 효율적이지 않습니다. 어쩌면 싱글 톤 클래스를 만들고 모든 스레드에 대한 참조로 전달할 것입니다. 네임 스페이스를 사용하는 것보다 조금 더 번거롭지 만 전역 변수가 변경되지 않도록해야합니까? – 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

관련 문제