2012-03-19 3 views
-3

double*을 반환하는 메소드를 쓰고 있습니다. 그러나이 메서드의 출력에서 ​​다른 메서드 동작을 기반으로하고 싶습니다. 나는 다음 '초기화'또는 '빌드'double* 및 중 하나를 반환 methodReturningArray()을하는 것이 적절하다C++ - 포인터를 테스트하십시오.

if (methodReturningArray()==0) 
{ 
    this_behavior(); 
} 
else 
{ 
    this_other_behavior(methodReturningArray()); 
} 

을하고 싶은이 double*은 적절하게 그

double* new_array ; 
return new_array ; 
처럼 돌아 초기화 또는 구축 할 수없는 경우

?

즉, double* 출력은 double* 출력을 만들 수 있도록 일부 속성이 완료되었는지 확인하는 부울 역할을합니다.

감사합니다.

+4

, 수 사람 * 포인트 * 내가 그것? – Griwes

+0

그것은 ... [?] 잊어 버려? . 변명. – octoback

+0

우리가 당신이 무엇을 요구하는지 모르겠다. 당신의 질문은 이상하게 말을하고, 우리는 당신이 도움을 원하는지 모르겠다. 그것을 바꿔 말할 수 있습니까? – user1118321

답변

1

포인터로 반환 한 내용이 초기화되지 않았 으면 return NULL을 사용하십시오. if(double* d = method()) (또는 원하는 다른 방식)으로 확인하십시오.

그러나 이것은 (나) 나의 할아버지 C++가 아니며 그렇게 할 이유가있을 때만 이와 같이 작성해야합니다.또는 std::vector 중 하나를 반환 값으로 감싸는 것을 선호하고 초기화 실패로 연결되는 동작이 다소 예외적 인 경우 예외를 throw합니다. 초기화하지 못하는 경우에는 반환 값을 boost::optional으로 감싸는 것이 좋습니다. 그러나 아마도 나는 OutputIterator이 걸린 것을 작성하여 클라이언트의 특정 컨테이너를 강제로 작성하지 않을 것입니다.

재해에 대한주의 사항 : double* d; return d은 클라이언트에게 임의의 메모리를 가리키는 포인터를 남깁니다. 그녀가 deleted[]이어야하는지 또는 유효한지 알아낼 수있는 방법이 없습니다. 항상 포인터를 초기화하십시오.

코드 조각 : 여기 질문을 볼 수 없습니다

// outputiterator 
template<typename OutputIterator> 
void myFunc(OutputIterator o) { 
    // fill stuff in 
    if(someThing) { 
    for(int i = 0; i < 5; ++i) 
    { 
     *o++ = 23; 
    } 
    } else { 
    // leave it empty 
    } 
} 

// client calls like: 
std::vector<double> v; 
myFunc(std::back_inserter(v)); 
if(!v.empty()) { 

} else { 

} 

// exception 
std::vector<double> myFunc() { 
    std::vector<double> v; 
    if(someThing) { v.push_back(23); return v; } 
    else throw std::runtime_error("Nargh!"); 
} 

// client 
try { 
    auto v = myFunc(); 
} catch(std::runtime_error err) { 

} 

// optional 
boost::optional<std::vector<double>> 
myFunc() { 
    std::vector<double> v; 
    if(someThing) { v.push_back(23); return v; } 
    else return boost::optional< std::vector<double> >(); 
} 

//client 
auto v = myFunc(); 
if(v) { 

} else { 

} 
+0

과 같은 안전한 모국어를 사용하십시오. 동의하지 않습니다; 이런 경우에는 어리석은 래퍼 나 심지어 부스트를 사용할 이유가 전혀 없으며, 코드를 복잡하게 만들고, 템플릿을 더 많이 사용하여 더 장황하고 컴파일 속도가 느려집니다 (특히 템플릿 처리와 관련해서는 정확하지 않은 gcc에서 특히 그렇습니다). 또는 EH조차 풀어 낼 때 쓸모없는 런타임 및 까만 마술의 톤을 추가하는. – q66

+1

@ q66'optional'은 컴파일 시간을 너무 많이 해칠뿐만 아니라 너무 장황하지도 않습니다. 다른 사람들이'new'를 삭제하는 것을 원하지 않을 것입니다. 그리고 여러분은 이와 같이 작성된 것으로 할당자를 변경해야하는 즉시 문제가 발생합니다. 하지만 그 논쟁은 너무 길어서 충분히 자주 생각해 왔습니다. 양쪽에는 장점이 있으며 목표에 대한 질문입니다. – pmr

+0

실제로 Boost가 상호 의존성으로 채워지므로 거의 모든 Boost 구성 요소를 포함하여 컴파일 시간이 아플 것입니다. 따라서 많은 코드가 확장되어야합니다. 나는 이것이 정말로 실질적인 이익이라고 생각하지 않는다. 삭제와 관련해서는 대부분의 경우에 문제가 없습니다. 수동 핸들링이 오류가 발생하기 쉬운 여러 가지 경우에 refcounting을 사용할 수 있지만 드문 경우입니다. – q66

0

기본적으로 3 가지 방법이 있습니다.

1) 오류가 발생하면 NULL을 반환합니다. 그런 다음 부울 검사를 문제없이 수행 할 수 있으며 대부분의 경우 충분합니다.

2) 반송 부울,이 같은 참조 또는 포인터 인수를 사용하여 두 * 출력 처리 :

bool methodReturningArray(double **out) { *out = ...; return true; } 

double *out; 
if (!methodReturningArray(&out)) this_other_behavior(out); else .... 

3) 예외 던지 - IMO 다소 복잡하고 unuseful있다.

초기화되지 않은 포인터를 반환하면 부울 값을 평가할 수 없으며 나중에 포인터가 매달린 포인터로 간주되므로 위험합니다.

+0

나는 C++에서 이러한 상황을보다 잘 처리 할 수있는 숙어가 있다고 생각한다. ('boost :: optional', value by return). – pmr

+0

@ pmr, 나는 그렇게 생각하지 않습니다. 그렇게하는 데 실제로 이점이 없으며 몇 가지 단점을 생각할 수 있습니다. 나는 정말로 "현대적인"C++ 스타일을 좋아하지 않는다. IMO는 절대적으로 아무 이유없이 물건을 지나치게 복제한다. – q66

+0

"이유가 없음"이라고 생각하는 경우 "배열 및 문자열 처리"범주의 버그 (http://www.viva64.com/en/a/0079/)를 살펴보십시오. * 그들 모두는 "현대적인"C++ 스타일을 사용하지 않기 때문에 발생합니다. 개인적으로 필자는 프로그래머 인 우리는 여전히 30 년 전에도 여전히 실수를 저지르고있다. 이 코드의 사용자가 포인터가 가리키는 배열의 크기를 어떻게 알 수 있습니까? 당신은 당신이 원하지 않는 것을 주장 할 수 있고 당신이 원하는 모든 것을 필요로하지 않을 수 있습니다, 그러나 당신은 그것을 "이유없이"주장 할 수는 없습니다. –

관련 문제