ProgramingTip

필드와 생성자 매개 변수에 동일한 이름을 사용할 수 있습니까?

bestdevel 2021. 1. 7. 21:29
반응형

필드와 생성자 매개 변수에 동일한 이름을 사용할 수 있습니까?



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

합법적입니까?


예, 합법적이며 모든 플랫폼에서 작동합니다. 멤버 변수 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;
};

참고 사항 (2) :

고유 한 변수 이름과 동일한 멤버 이름을 사용 하려는 한 가지 이유 는 다음과 같은 경향이 적기 때문입니다.

class  A
{

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

초기화 초기화 목록에서 초기화하기 전에 _myVariable을 사용합니다.


이 주제와 관련하여 혼란을 야기 할 수있는 것 하나는 컴파일러가 변수의 우선 순위를 지정하는 방법입니다. 예를 들어 생성자 인수 중 하나가 클래스 멤버와 같은 경우 초기화 목록에 다음을 사용할 수 있습니다.

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

그러나 위의 코드는 이것과 같은 효과가 있습니까?

MyClass(int a)
{
    a=a;
}

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

인수 값을 클래스 멤버 "a"에 할당하려면 클래스 인스턴스 내에서 값을 참조하고 있음을 컴파일러에 알려야합니다 .

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

좋습니다.하지만 다음과 같이했다면 어떨까요 ( "a"라는 인수가 없다는 점에 유의하세요).

MyClass() : a(a)
{
}

이 경우 컴파일러는 먼저 "a"라는 인수를 찾고 아무것도 없다는 것을 발견했을 때 클래스 멤버 "a"의 값을 클래스 멤버 "a"에 할당합니다. .

마지막으로 초기화 목록의 클래스 멤버에만 값을 할당 할 수 있으므로 다음과 같은 경우 오류가 발생합니다.

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

형식 매개 변수와 멤버의 이름이 같으면 생성자 내에서이 포인터를 사용하여 멤버 변수를 사용하는 것에주의하십시오.

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

Legal : 예, Brian이 설명했듯이 컴파일러는 이니셜 라이저 목록에 예상되는 이름이 멤버 (또는 기본 클래스) 여야하며 다른 것은 아니어야한다는 것을 알고 있습니다.

좋은 스타일 : 아마도 그렇지 않을 것입니다. (당신을 포함한 많은 프로그래머들에게) 그 결과는 분명하지 않습니다. 매개 변수에 다른 이름을 사용하면 코드가 합법적으로 유지되고 동시에 좋은 스타일이됩니다.

다음 중 일부를 작성하는 것이 좋습니다.

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


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

이 관행의 문제는 합법적 일 수 있지만 컴파일러는 -Wshadow를 사용할 때 그림자가있는 변수를 고려하고 다른 코드에서 이러한 경고를 난독 화한다는 것입니다.

또한, 사소하지 않은 생성자에서 멤버 이름 앞에 this->를 넣는 것을 잊고 실수를합니다.

Java는 이것을 허용하지 않습니다. 그것은 나쁜 습관이며 피해야합니다.

참조 URL : https://stackoverflow.com/questions/268587/can-i-use-identical-names-for-fields-and-constructor-parameters

반응형