2009-02-23 8 views
13

저는 C++로 오랫동안 프로그래밍되어 있었고 아직 한 가지에 대해 의심이 있습니다. 다른 사람의 코드에서 많은 장소에서 나는 같은 것을 참조 : 나는/가져 그 코드를 사용해야하는 경우이것을 사용하는 이유가 있습니까?>

void Classx::memberfunction() 
{ 
    this->doSomething(); 
} 

, 나는 단순히 this-> 부분을 제거를, 나는 깨진 또는 일부를 갖는 것을 본 적이 없다 부작용.

void Classx::memberfunction() 
{ 
    doSomething(); 
} 

그래서 이러한 구조를 사용하는 이유는 무엇입니까?

편집 : 여기서는 멤버 함수에 대해 설명하고 변수는 아닙니다. 멤버 변수와 함수 매개 변수를 구별하고자 할 때 사용할 수 있음을 이해합니다.

편집 : 명백한 중복 : Are there any reasons not to use "this" ("Self", "Me", ...)?

답변

8

멤버 함수와 동일한 이름으로 정의 될 수있는 매크로가 있고 확실하게 정의되지 않은 경우 확실하지 않은 경우 컴파일러 오류를 트리거하도록 보장하십시오.

농담이 아닙니다. 나는 이런 이유로 정확히 이것을해야만했음을 확신합니다!

+3

회원 이름을 해결할 수있는 또 다른 방법은 아무도 없다고합니다. http://en.wikipedia.org/wiki/Scope_resolution_operator를 사용하여 예 : Classx :: doSomething(); –

+7

함수에 적용하면 가상 함수의 어떤 버전이 호출되는지 보장하는 효과가 있으며 다형성을 방지하고 일반적으로 재정의 된 함수의 부모를 호출하는 데 사용됩니다. 이것은 doSomething()의 안전한 등가물이 아닙니다. –

+1

사실이 경우에 대해 잊어 버렸습니다. Andy에게 감사드립니다. –

2

난 당신이 분명히 일을하기 위해 추가 괄호를 사용할 때처럼 읽기 쉽게 생각할 수 있습니다.

1

필자는 컴파일러와 다를 바는 없다고 생각하지만 필자는이 코드를 스스로 문서화한다고 생각하기 때문에 항상이 글을 쓰고있다.

2

나는 주로 독자에게 도움이된다고 생각합니다. 그것은 호출되는 것이 객체에 대한 메소드이며, 일반적인 함수가 아니라는 것을 명시합니다. 코드를 읽을 때, 호출 된 함수가 현재 객체의 필드를 변경할 수 있다는 것을 아는 것이 도움이 될 수 있습니다.

25

같은 이름의 동일한 범위에 다른 변수가있는 경우 this->는 모호성을 제거합니다.

void Bar::setFoo(int foo) 
{ 
    this->foo = foo; 
} 

또한 회원 변수/기능을 참조하고 있음을 분명히합니다.

+0

이런 식으로 사용하면 나쁜 명명 규칙에 대한 반창고가됩니다. 코드를 불필요하게 혼란스럽게 만듭니다. –

+4

그냥 질문에 대답하십시오. – drby

+0

변수에 관한 질문을하지 않았습니다. 이는 알려진 문제입니다. 나는 회원 기능에 대해 물었다. –

1

동음 이의 해제 : 동일한 네임 스페이스에 다른 유사한 명명 함수/변수가있는 경우? 나는 다른 어떤 이유로도 사용법을 본 적이 없다.

1

선택의 여지가 있습니다. 이걸 사용하면 더 명확 해집니다. 그러나 당신이 그것을 좋아하지 않는다면, 당신은 그것을 배제 할 수 있습니다.

4

로 "코드 이유"는 부재로부터 (즉 우선) 로컬 변수 또는 값을 구별 :

class Foo 
{ 
    int member; 
    void SetMember(int member) 
    { 
     this->member = member; 
    } 
} 

그러나, 그 시작 나쁜 practive이다 및 보통 로컬 해결 될 수있다.

두 번째 이유는 더 많은 "환경"입니다. Intellisense가 때때로 내가 실제로 찾고있는 것을 필터링하는 데 도움이됩니다. 그러나, 나는 또한 이것을 사용하여 내가 찾고있는 회원을 찾으면 이것을 제거해야한다.

그렇습니다. 좋은 이유가 있지만, 모두 일시적입니다 (장기적으로는 좋지 않습니다).

+2

나는 이것이 반드시 나쁜 습관이라고 동의하지 않는다. 개체 나 변수에 대해 선명하고 명료하며 불분명 한 이름을 가진 이유는 무엇입니까? –

+0

IMO 코딩 표준은 공개 속성 대 내부 구성원 대 지역 변수/매개 변수를 명확하게 만들어야합니다. 'm_'을 타이핑하는 것이 싫은만큼, 좋은 이유가 있습니다. – peterchen

+0

명확히하기 : 문제가 발생해도 괜찮다고 생각하지만 자주 발생하면 가독성 문제와주의 슬립 버그에 대한 초대장을받을 가능성이 큽니다. 자, 여러분의 표준은 'this->'가 항상 '구별 자'로 사용되도록 선언 할 수도 있지만 좋은 선택이라고 생각하지 않습니다. – peterchen

2

이것은 실제로 스타일의 문제이며 Java 및 C#과 같은 다른 많은 언어에도 적용됩니다. 어떤 사람들은 명시 적으로 this (또는 self 또는 Me 또는 무엇이든) 다른 사람은 그렇지 않은 것을 선호합니다. 스타일 가이드 라인에있는 것이면 무엇이든 가지고 다니십시오. 프로젝트라면, 지침을 결정할 수 있습니다.

+0

그리고 일부 언어 (PHP, Python)도이를 시행합니다. 내가 그 (것)들에있는 OO를하는 것을 싫어하는 이유의 한. –

1

필자는이 포인터를 명시 적으로 지정하지 않고 선호합니다. 메소드 호출의 경우 값을 많이 추가하지는 않지만 로컬 변수를 멤버 변수와 구별하는 데 도움이됩니다.

2

이 사용되는 변수가 로컬 또는 글로벌 변수에 반대되는 멤버 변수라는 사실에 대해 명시 적으로 수행됩니다

여기에 내 자신의 질문입니다. 대부분의 경우에는 필요하지 않지만 더 엄격한 범위에서 동일한 이름의 선언으로 변수를 트러블 한 경우 범위에 대해 명시 적으로 도움이 될 수 있습니다.

내가 일한 회사에서 회원 변수 앞에 "m_"을 붙였습니다. 때로는 도움이 될 수 있으며 "this->"를 사용하는 것이 훨씬 좋습니다.

편집 : the GCC docs에 대한 링크를 추가하면 비 의존형 조회를 올바르게 수행하려면 this->를 사용해야하는 경우를 설명하는 the GCC docs에 대한 링크를 추가하십시오.

35

정말 차이가 파생 클래스에서 템플릿에 만드는 유일한 장소 :

template<typename T> 
class A { 
protected: 
    T x; 
}; 

template<typename T> 
class B : A<T> { 
public: 
    T get() { 
    return this->x; 
    } 
}; 

인해 details in the name lookup in C++ compilers에, 그것은 x 클래스의 (상속) 구성원임을 명시 적으로 분명하게해야한다, 가장 쉬운 방법은 this->x입니다. 그러나 이것은 다소 수수께끼 인 경우입니다. 템플릿 클래스 계층이 없으면 클래스 멤버에 액세스하기 위해 명시 적으로 this을 사용할 필요가 없습니다.

1

정확한 상황을 기억할 수는 없지만 GCC를 사용하여 코드를 성공적으로 컴파일하려면 "this-> membername"을 작성해야하는 매우 드문 경우를 보았습니다. 내가 기억하는 모든 것은 모호성과 관련이 없으므로 해결 방법을 파악하는 데 다소 시간이 걸렸습니다. 같은 코드가 Visual Studio에서 this-> 사용하지 않고 잘 컴파일되었습니다.

+0

이것은 종속 템플릿 매개 변수와 관련이 있습니다.이 링크는 좋은 설명을 제공합니다. http://gcc.gnu.org/onlinedocs/gcc/Name-lookup.html –

0

저는 이것을 사용하여 연산자를 암시 적으로 호출합니다 (아래의 반환 및 매개 변수 유형은 코드 작성을위한 더미입니다).

struct F { 
    void operator[](int); 
    void operator()(); 

    void f() { 
    (*this)[n]; 
    (*this)(); 
    } 

    void g() { 
    operator[](n); 
    operator()(); 
    } 
}; 

나는 *this 구문을 더 좋아합니다. 그것은 약간 다른 의미를 가지고 있습니다. *this을 사용하면 멤버와 동일한 이름을 가진 비 멤버 연산자 함수가 숨겨지지 않습니다.

+0

"'* this'는 멤버와 같은 이름을 가진 비 멤버 연산자 함수를 숨기지 않는다는 것을 무엇을 의미합니까? 예제를 제공해 줄 수 있습니까? – rlbond

+0

예 :'struct A {void operator *(); void f(); }; void 연산자 * (A, A); void A :: f() {A a; 연산자 * (a, a); }'<- 이것은 구성원 연산자가 전역 연산자 *를 숨기므로 부적절합니다. 그러나 'a * a'(표현식 구문)를 작성하면 조회가 구성원과 비회원을 구분하여 분리되므로 잘 작동합니다. –

+0

(이 표준은 13.3.1.2/10에 더 좋은 예를 보여줍니다). –

0

좋은 답변이 많이 있지만,이 중 일부는 긴 함수의 코드를 읽을 때 소스 코드에서 this->를 사용하면 더 쉽게 읽을 수 있지만 짧은 함수 일지라도 코드를 상상해보십시오. :

bool Class::Foo() 
{ 
    return SomeValue; 
} 

이 코드에서 보면, SomeValue가 무엇인지 명확하게 알 수 없습니다.심지어 일부 #DEFINE, 또는 정적 변수가 될 수 있지만, 당신은

bool Class::Foo() 
{ 
    return this->SomeValue; 
} 

를 작성하는 경우 당신은 명확 someValue와는 같은 클래스의 비 정적 멤버 변수는 것을 알고있다.

그래서 함수 나 변수의 이름이 다른 이름과 충돌하지 않도록하는 것이 도움이 될뿐만 아니라 다른 사람들이 소스 코드를 읽고 이해하기 쉬워지며 자체 문서 작성 소스 코드는 때로는 매우 중요합니다.

2

또 다른 경우는 C++ 11이 람다에 있는데, this이 캡처 된 장면에 도착했습니다.

당신은 같은 것을 할 수 있습니다 : 당신의 람다 클래스 내에서 생성되는

class Example 
{ 
    int x; 
public: 
    std::function<void()> getIncrementor() 
    { 
    return [this]() -> void 
    { 
     ++(this->x); 
    } 
    } 
}; 

있지만, 그것은 단지를 캡처하여 지역 변수에 액세스 할 수 있습니다 또는 this을 캡처 (컴파일러는 C++ 14 않는 경우) . 두 번째 경우, 람다 몸체 내부에는 단순히 x이없고 단지 this->x입니다.

관련 문제