2013-12-17 3 views
9

초기화 표준 : : 벡터 : : 문자열은

std::vector<std::string> Object::getTypes(){ 
    std::vector<std::string> types; 
    types.push_back("type1"); 
    types.push_back("type2"); 
    types.push_back("type3"); 
    return types; 
} 

인가 이건 단지 스타일 선택인가요? 아니면 제가 빠진 것이 있습니까? 어떤 도움이라도 대단히 감사하겠습니다. 이건 너무 미안해.

업데이트 : 실제로 동일한 방법을 재정의하는 다른 클래스가 발견되면 어떤 방식 으로든 그렇게하므로 더 모호합니다. 나는 그것들을 모두 동일하게 만들 것이지만 더 좋은 접근법을 선호 할 것이다.


편집

는 배열의 첫 번째 두 요소와 벡터를 초기화하기 때문에 위의 레거시 코드가 올바르지 있습니다. 그러나이 오류는 주석에서 논의되었으며 따라서 보존되어야합니다. (types[] 한 번만 할당되고 push_back가/재 할당이 발생 할 수 있기 때문에) 당신이 발견

... 
    return std::vector<std::string> (types, types + 3); 
... 
+2

첫 번째 주문은 원칙적으로 메모리 재 할당을 필요로하지 않기 때문에 더 효율적일 수 있습니다. 함수 호출도 적습니다. C++ 11에서'return std :: vector { "type1", "type2", "type3"};'이라고 말할 수 있습니다. – juanchopanza

+2

@juanchopanza 또한,이 버전에서는 코드와 데이터의 분리가보다 명확하므로 구문 론적으로보다 명확합니다. –

+0

나의 이전 코멘트에 대한 정정 : C++ 11에서는'return { "type1", "type2", "type3"};'과 같은 단어를 적게 사용할 수 있습니다. – juanchopanza

답변

1

첫 번째 예의 배열 types은 정적으로 선언됩니다. 이는 메모리에 한 번만 존재 함을 의미합니다. 따라서 반환 할 항목과 정적 메모리에 살기위한 세 가지 옵션이 있습니다. 그런 다음 반환 할 벡터를 만들면 배열의 시작과 끝을 반복자로 전달하여 한 번에 메모리를 할당 할 수 있습니다.

이렇게하면 push_back을 연속적으로 호출하지 않으므로 벡터에서 내부 메모리 블록을 재 할당 할 필요가 없습니다.

또한 반환 호출의 일부로 벡터를 구성하면 이전 컴파일러에서 return value optimization 일을 더 쉽게 할 수 있습니다.

+0

RVO는 모든 코드에 동등하게 적용됩니다. 심지어 "오래된"컴파일러 (많은 컴파일러가 실제로는 최신 컴파일러보다 좋았습니다). –

5

코드가 더 효율적입니다 다음과 같이

올바른 초기화

읽기 있어야합니다. 차이는 있지만 한계가 있으며 getTypes을 (상대적으로 큰) 루프로 호출하지 않는 한 전혀 문제가되지 않습니다 (큰 루프에서 호출해도 큰 문제가 아닐 것입니다).

이와 같이 구체적인 성능 문제가 발생하지 않는 한 스타일 선택입니다. 당신이 C++ (11) 할 수있는 컴파일러와 라이브러리가있는 경우

9

, 이니셜 라이저 목록을 반환하는 것은 충분해야한다 :

std::vector<std::string> Object::getTypes(){ 
    return {"type1","type2", "type3"}; 
} 
3

은 기본적으로는 스타일의 선택입니다. 나는 아마도 더 비슷한 것을 할 것입니다.

std::vector<std::string> Object::getTypes(){ 
    static std::string types [] = {"type1","type2", "type3"}; 
    return std::vector<std::string> (types, 
        types + (sizeof(types)/sizeof(std::string))); 
} 

당신이 유형의 수를 바꿀 수있게 해주고, 다음 줄의 카운트를 기억하지 않아도됩니다.

+0

이렇게하면 "std :: vector '초기화에 대해 일치하는 생성자가 없습니다. 처음에 나는 당신이 말하는 것처럼 그것을해야한다고 생각했지만 컴파일되지 않았습니다. –

+0

@AndresBucci'std :: vector (types, types + sizeof (types)/sizeof (std :: string)); ' – juanchopanza

+1

@AndresBucci - 편집 내용보기, juanchopanza 님의 의견이 약간 어긋납니다. 기본적으로 vector에는 (Type *, nelements) 생성자가 없으며 (iterator, iterator) 생성자가 있습니다. –

0

이 스타일을 반복기 (및 C++ 11의 초기화 초기화 및 초기화 목록)와 함께 사용하는 이유 중 하나는 코드에서 데이터를 분리하는 데 도움이된다는 것입니다.

많이 반복하면 나는 그것을 필사적으로 리팩터링해야하므로 나쁠 때가 많다. 또한 실제로 데이터로 컨테이너를 초기화해야하는 경우 데이터를 생성하는 코드가 아닌 데이터 목록을보고 싶습니다. 원본 버전에서 찾은 방법은 그 원칙을 더 잘 충족시킵니다.