문제

C ++에서는 if 문에서 변수를 초기화 할 수 있습니다.

if (CThing* pThing = GetThing())
{
}

왜이 나쁘거나 좋은 스타일을 고려할 것인가? 혜택과 단점은 무엇입니까?

개인적으로 나는이 스타일을 좋아하기 때문에 pthing 변수의 범위를 제한하기 때문에 null 일 때 우연히 사용할 수 없습니다. 그러나 나는 당신이 이것을 할 수 없다는 것을 좋아하지 않습니다.

if (CThing* pThing = GetThing() && pThing->IsReallySomeThing())
{
}

위의 작업을 수행하는 방법이 있다면 게시하십시오. 그러나 그것이 불가능하다면, 나는 여전히 이유를 알고 싶습니다.

질문은 여기에서 빌려 왔습니다. 유사한 주제이지만 PHP.

도움이 되었습니까?

해결책

중요한 것은 C ++의 선언이 표현이 아니라는 것입니다.

bool a = (CThing* pThing = GetThing()); // not legit!!

if 문서에서 선언과 부울 논리를 모두 수행 할 수는 없습니다. C ++ 언어 사양은 구체적으로 표현 또는 선언을 허용합니다.

if(A *a = new A)
{
    // this is legit and a is scoped here
}

표현식에서 A가 한 용어와 다른 용어 사이에 정의되어 있는지 어떻게 알 수 있습니까?

if((A *a = new A) && a->test())
{
    // was a really declared before a->test?
}

총알을 물고 내부를 사용하십시오. 범위 규칙은 유용하고 논리가 명시 적입니다.

if (CThing* pThing = GetThing())
{
    if(pThing->IsReallySomeThing())
    {
    }
}

다른 팁

장점에 대해 :

변수를 처음으로 필요로 할 때는 항상 라인이 아니라 변수를 정의하는 것이 좋습니다. 코드의 가독성 향상을위한 것입니다. 코드의 가독성이 향상됩니다. 스크롤 및 정의 된 위치를 검색하지 않고 Cthing이 무엇인지 알 수 있기 때문입니다.

또한 루프/if 블록으로의 범위를 줄이면 코드 블록을 실행 한 후 변수가 참조되지 않아서 쓰레기 수집 후보가됩니다 (언어 가이 기능을 지원하는 경우).

if (CThing* pThing = GetThing())

그것은이다 나쁜 스타일, 내부 if 당신은 부울 표현을 제공하지 않습니다. 당신은 a CThing*.

CThing* pThing = GetThing();
if (pThing != NULL)

이것은 좋은 스타일입니다.

일반적으로 그렇게하지 않는 한 가지 이유는 조건부 테스트에서 누락 된 '='의 일반적인 버그 때문입니다. 나는 그것들을 잡기 위해 오류/경고가 설정된 후 Lint를 사용합니다. 그런 다음 조건부 내부의 모든 과제에 대해 소리칩니다.

FYI만이 오래된 Microsoft C ++ Compliers (Visual Studios 6 및 .NET 2003 생각) 중 일부는 어떤 경우에는 범위 규칙을 따르지 않습니다.

for(int i = 0; i > 20; i++) {
     // some code
}

cout << i << endl;

나는 범위를 벗어나야하지만 그것은 유효한 코드였습니다. 나는 그것이 기능으로 재생되었다고 생각하지만 제 생각에는 단지 규정 준수가 아닙니다. 표준을 준수하지 않는 것은 나쁘다. IE 및 Firefox에 대한 웹 개발자와 마찬가지로.

대 VS를 가진 사람이 여전히 유효한 지 확인하고 확인할 수 있습니까?

이것 ~해야 한다C ++에서는 작동하지 않습니다 ~부터비록 그것이 지원 되더라도 단락 평가. 아마도다음을 시도하지 마십시오.

if ((CThing* pThing = GetThing()) && (pThing->IsReallySomeThing()))
{
}

오류 .. 참조 Wesley Tarle의 대답

경고 메시지를 방지하기 위해 추가 세트 ()에 할당을 동봉 할 수도 있습니다.

나는 그것을 일종의 위험한 것으로 본다. 아래 코드는 훨씬 더 안전하며 둘러싸는 버팀대는 여전히 원하는 방식으로 pthing의 범위를 제한합니다.

getthing ()가 때때로 null을 반환한다고 가정하므로 if () 문에 그 재미있는 조항을 넣는 이유입니다. 그것은 null 포인터에서 isreallysomething ()가 호출되는 것을 방지합니다.

{
    CThing *pThing = GetThing();
    if(pThing ? pThing->IsReallySomeThing() : false)
    {
    // Do whatever
    }
}

또한 C ++ 코드를 작성하는 경우 조건부 명령문 (선언의 일부가 아닌)에서 컴파일러를 경고하려고합니다.

수용 가능하고 좋은 코딩 연습입니다. 그러나 낮은 수준의 코딩 배경에서 오지 않는 사람들은 아마도 동의하지 않을 것입니다.

너무 많은 것들. 우선, 베어 포인터. 반드시 피하십시오. 참조, 선택 사항, 고유 한 _ptr, shared_ptr을 사용하십시오. 최후의 수단으로서 포인터 소유권을 다루는 자신의 수업을 작성하십시오.

C ++ 11이 필요한 경우 균일 초기화를 사용합니다 (C ++ 14 C ++ 11 결함을 피하기 위해 선호) : - 피를 피하고 혼동을 피하고 인수가있는 경우 인수를 확인하는 데 더 엄격합니다.

if (CThing thing {})
{
}

구현해야합니다 operator bool cthing에서 bool로 예측 가능한 변환을 얻습니다. 그러나 코드를 읽는 다른 사람들은 operator bool 곧. 명시 적 방법 호출은 일반적으로 더 읽기 쉽고 안심입니다. C ++ 17이 필요한 경우 Initializer Syntax를 사용하십시오.

if (CThing thing {}; thing.is_good())
{
}

C ++ 17이 옵션이 아닌 경우 다른 사람들이 제안한 경우 위의 선언을 사용하십시오.

{
  CThing thing {};
  if (thing.is_good())
  {
  }
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top