2017-04-18 7 views
0

두 가지 메서드가있는 클래스가 있다고 가정합니다. 그들 중 하나는 컨테이너에서 객체를 찾아 값으로 반환해야하며 다른 객체는 참조로 반환해야합니다. 당연히 첫 번째 방법은 const (this의 의미는 const)이고 두 번째 방법은 그렇지 않기를 바란다.C++에서 동일한 항목의 값과 참조를 반환하는 두 가지 메서드를 작성하는 최적의 방법

둘 다 의존하는 세 번째 방법을 도입하지 않고도이 두 가지 방법간에 코드를 재사용 할 수 있습니까? 아래에서는 문제의 장난감 예를 들었는데, find 단계가 실제로 훨씬 더 복잡하다고 상상해보십시오. "가능한 구현 1"의

아래 인해 I는 (const) get_value 내에서 (비 const) get_ref 부르고 있다는 사실에 에러가있다. "가능한 구현 2"에서 참조는 값의 임시 복사본으로 만들어지며 이는 물론 주요한 문제입니다.

const 참조가 필요한 경우 물론 문제는 없지만 실제로는 일반적인 참조를 원한다고 가정합니다.

// Header: 

#include <string> 
#include <map> 
using std::string; 
using std::map; 

class Test { 
    public: 
     map< string, string > stuff; 
     string & get_ref(const string key); 
     string get_value(const string key) const; 
}; 


// Possible implementation 1: 

string Test::get_value(const string key) const { 
    return get_ref(key); 
} 

string & Test::get_ref(const string key) { 
    return stuff.find(key)->second; 
} 


// Possible implementation 2 (obviously wrong, but here for the sake of pointing that out): 

string Test::get_value(const string key) const { 
    return stuff.find(key)->second; 
} 

string & Test::get_ref(const string key) { 
    return get_value(key); 
} 
+0

두 번째 구현에서'get_ref'가 반환하는 것에 대해 조금 생각해보십시오. 실제로 컴파일러가 컴파일러에게 무엇을 말하려한다면? –

+0

관련없는 노트에서, 키가 발견되지 않고'find' 함수가'end' 반복자를 리턴하면 어떻게되는지 생각해야합니다. –

+0

@Someprogrammerdude 만약 당신이 임시의 반환을 암시하는, OP는 이미 두 번째 구현을 사용하지 않는 이유로 언급했다 –

답변

0

직접 질문에 대답하기 위해, 개인/세 번째 방법을 사용하지 않도록하는 유일한 방법은 멀리 thisconst -ness 캐스팅하는 것입니다. 두 개의 다른 문제에 조금 더 넓은보고, 이제

string Test::get_value(const string key) const { 
    return const_cast<Test*>(this)->get_ref(key); 
} 

을 : :은 "가능한 구현 한"다음 alter입니다 같이 사용

첫째로, 당신은 get_ref()을 변경해야합니다 그래서 그것은 stuff.find(key) 반환 end() 경우 합리적인 무언가를 (one-past-the-end 반복자). 예외를 던지거나 빈 문자열을 반환하는 옵션이 있습니다.

두 번째로 간단한 효율성 향상은 메서드 매개 변수가 문자열을 값으로 전달하므로 쉽게 안전하게 const string& key으로 전달할 수 있습니다.

+0

나는 @someprogrammerdude와 같은 시간에 위의 내용을 입력했다고 생각합니다. -S –

+0

고마워, 내가 const_cast 함께 갈 것 같아요. 나는 오류 처리가 있어야한다는 것을 이해했다는 것을 위에서 언급했다. 방금 예제를 가능한 한 짧게 유지하려고했습니다 (각 함수에 한 줄 씩). 값 또는 참조로 전달하는 상대적인 속도에 관해서는, 내 이해는 작은 내장 유형의 경우 컴파일러에 더 많은 영향을 미칩니다. 그러나 이것은 내가 거의 알지 못하는 것입니다. – sasquires

+0

내 자신의 대답은 제쳐두고, 빈 문자열이나 비슷한 것을 반환 할 때주의해야합니다.주의하십시오. 'return "";'은 안전하지 않습니다 (로컬/임시 객체에 대한 참조를 반환합니다). 'static' 멤버 나 정적 로컬 변수를 선언하고 리턴하는 것이 더 낫습니다. –