2008-11-06 4 views

답변

39

예 모든 플랫폼에서 작동하며 올바로 작동합니다. 멤버 변수 a를 전달 된 값 a로 올바르게 초기화합니다.

좀 더 깨끗한 것으로 이름이 다를 수는 있지만 전부는 아닙니다. 나는 개인적으로 실제로 같은 변수 이름으로 그것을

초기화 목록을 많이 :) 사용 작동 다음과 같이 초기화 목록에서 초기화 항목의 구문이기 때문이다 :

< 회원 > (< 값을 >)

class A 
{ 

    A(int a) 
    : a(5)//<--- try to initialize a non member variable to 5 
    { 
    } 
}; 

당신은 얻을 것이다 (그것은 컴파일되지 않습니다) :

내가이 수행하는 간단한 프로그램을 작성하여 위의 쓴 확인할 수 있습니다 다음과 같이 컴파일 오류가 발생합니다. A에 'a'라는 필드가 없습니다.

class A 
{ 

    A(int myVarriable) 
    : myVariable(myVariable)//<--- Bug, there was a typo in the parameter name, myVariable will never be initialized properly 
    { 
    } 
    int myVariable; 
}; 
: 매개 변수 이름은 다음에 더 많은 경향이있을 것입니다 당신이 같은 멤버 이름을 사용하는을 원하지 않는 이유에

한 가지 이유 : 보조 노트에


한 이유는 Y : 메모 측면 (2)에


class A 
{ 

    A(int myVariable_) 
    { 
    //<-- do something with _myVariable, oops _myVariable wasn't initialized yet 
    ... 
    _myVariable = myVariable_; 
    } 
    int _myVariable; 
}; 

이 대형 초기화 목록에 일어날 수있는 당신이 초기화에서 초기화하기 전에 _myVariable를 사용 매개 변수 이름은 다음에 덜 경향이있을 것입니다으로 OU 같은 멤버 이름을 사용하는을 할 수 있습니다 명부.

+2

그것은 맛의 문제이다. 나는 똑같은 이름을 지어주는 것을 선호한다. 그래서 네임 스페이스를 널리 사용합니다. –

+1

매우 자주 개인 필드에 대해 "a_"또는 "_a"와 같은 이름을 찾을 수 있습니다. –

+0

멤버 변수는 종종 m_a 또는 _a입니다. 범위가 지정된 변수는 종종 a_입니다. –

4

법률 : 예, Brian이 설명한대로 컴파일러는 이니셜 라이저 목록에서 기대할 이름이 다른 것이 아니라 구성원 (또는 기본 클래스)이어야 함을 알고 있습니다.

좋은 스타일 : 대부분의 프로그래머가 아닙니다 (사용자를 포함하여) 결과가 분명하지 않습니다. 매개 변수에 다른 이름을 사용하면 코드를 합법적으로 유지하면서 동시에 좋은 스타일을 만들 수 있습니다. 공식 매개 변수와 멤버가 같은 이름의 경우 다음 멤버 변수를의

class C { 
    T a; 
public: 
    C(T a): a(a) { 
this->a.sort ;//correct 
a.sort();//will not affect the actual member variable 
} 
}; 
+1

아니, 나에게있어서 결과는 분명하다. a (a) 구성이 합법적이라면 그 a가 다른 것을 분명히 의미합니다.C++에서는 정말 합법적인지 확실하지 않았습니다. –

+1

구현시 충돌을 피하기 위해 앞에 밑줄이있는 식별자를 사용할 때 매우주의해야합니다. 여기에서와 같이 소문자로 끝나면 실제로 괜찮습니다. 그러나 완전히 피하는 것이 가장 좋다고 생각합니다. 자세한 내용은 228783 번 질문을 참조하십시오. – tragomaskhalos

+0

두 가지 장점이 있습니다. –

7

:

나는 몇 가지를 작성 선호 이 주제와 관련하여 혼동을 일으킬 수있는 사항은 컴파일러에서 변수의 우선 순위를 지정하는 방법입니다.

MyClass(int a) : a(a) 
{ 
} 

을하지만 위의 코드는 다음과 같은 효과를 않습니다 생성자의 인수 중 하나가 클래스 멤버로 이름이 같은 경우 예를 들어, 초기화 목록에서 다음을 쓸 수 있을까?

MyClass(int a) 
{ 
    a=a; 
} 

대답은 없습니다. "a"를 생성자의 본문에 입력 할 때마다 컴파일러는 "a"라는 로컬 변수 또는 생성자 인수를 먼저 찾고, 찾을 수없는 경우에만 "a"라는 클래스 멤버를 찾기 시작할 것입니다. (그리고 아무도 없으면 "a"라는 전역 변수를 찾는다). 결과는 위의 문장 "a = a"는 인수 "a"에 저장된 값을 인수 "a"에 할당하여 쓸모없는 문장으로 만듭니다.

MyClass(int a) 
{ 
    this->a=a; 
} 

좋아,하지만 "A는"당신은 당신이 안에이 클래스 인스턴스를 값을 참조하는 컴파일러에 알려 필요한 클래스 멤버에 대한 인수의 값을 할당하기 위해

당신이 뭔가를 한 경우 ("A"라는 인수가없는 것을 알) :

MyClass() : a(a) 
{ 
} 

글쎄, 컴파일러가 먼저 호출 인수를 찾을 것입니다 경우에 "a"는 그것을 발견 할 때 어떤 것이 든 클래스 멤버 "a"의 값을 클래스 멤버 "a"로 보내면 아무 것도하지 않을 것입니다.

는 마지막으로 다음과 같은 오류가 발생합니다, 그래서 당신은 초기화 목록에 클래스 멤버에 값을 할당 할 수 있다는 것을 알고 있어야합니다

MyClass(int x) : x(100) // error: the class doesn't have a member called "x" 
{ 
} 
+0

흠 ... 그것들을 다르게 명명하는 훌륭한 이유 인 것 같습니다. 좋은 지적. –

+0

이것은 함수의 구현에서 값에 의한 입력 매개 변수를 변경하지 않고'const'를 사용하는 좋은 이유입니다. – Ruslan

16

하나를 사용하는 생성자 내에서이 포인터를 사용하여 조심

class C { 
    T a_; 
public: 
    C(T a): a_(a) {} 
}; 


class C { 
T a; 
public: 
C(T value): a(value) {} 
}; 
2

이 연습 문제, 그것은있을 수 있지만 법적를,이다 컴파일러는 -Wshadow가 사용될 때 그림자가있는 변수를 고려할 것이고 다른 코드의 경고를 난처하게 할 것입니다.

또한, 단순하지 않은 생성자에서 실수를하면 멤버 이름 앞에 this->를 넣는 것을 잊어 버릴 수 있습니다.

자바는 이것을 허용하지 않습니다. 나쁜 관행이므로 피해야합니다.

관련 문제