C ++ 클래스의 멤버 변수에 접두사를 사용하는 이유


150

많은 C ++ 코드는 멤버 변수를 표시하기 위해 구문 규칙을 사용합니다. 일반적인 예는 다음과 같습니다.

  • 공개 멤버의 m_ memberName (공개 멤버가 전혀 사용되지 않는 곳)
  • 개인 구성원 또는 모든 구성원의 _ memberName

다른 사람들 은 멤버 변수가 사용될 때마다 this-> 멤버를 사용하려고합니다 .

내 경험상 가장 큰 코드 기반은 이러한 규칙을 일관되게 적용하지 못합니다.

다른 언어에서는 이러한 규칙이 훨씬 덜 널리 퍼져 있습니다. Java 또는 C # 코드에서만 가끔 나타납니다. 루비 또는 파이썬 코드에서는 본 적이 없다고 생각합니다. 따라서 멤버 변수에 특별한 마크 업을 사용하지 않는 최신 언어가있는 추세 인 것 같습니다.

이 컨벤션은 오늘날 C ++에서 여전히 유용합니까, 아니면 단지 비동기 일뿐입니다. 특히 라이브러리 전체에서 일관되지 않게 사용됩니다. 다른 언어는 멤버 접두어없이 할 수 있음을 보여주지 않았습니까?


15
나는 그것을 선호한다; 복잡한 코드베이스에서는 어떤 vars가 로컬이고 어떤 var가 아닌지를 아는 것이 중요 할 수 있습니다. 나는 일반적으로 별도의 입력과 (이름이 그렇게하도록 강요하는 반면) 옵션의 많은으로 내가 찾을 수있는 this->을 강제 통해 접두사를 사용

5
@ for attribute 및 속성을 직접 사용하는 것보다 우선 접근자를 생성하는 관용구 때문에 Ruby에서 본 적이 없습니다.
Steve Jessop

6
PEP 8 에 따르면 비공식 멤버 변수는 파이썬에서 밑줄로 시작합니다 (예 :) self._something = 1.
Nathan Osman

2
편집기의 구문 강조 표시를 사용하여이를 식별해서는 안됩니까?
너무

2
this->member파이썬 코드에서 이에 상응하는 것을 보았습니다 . 파이썬에서는 일반적으로 존재 self.member하며 이는 규칙 일뿐만 아니라 언어에 필요합니다.
matec

답변:


48

밑줄을 사용할 때는주의해야합니다. 단어의 대문자 앞에있는 밑줄은 예약되어 있습니다. 예를 들면 다음과 같습니다.

_Foo

_엘

모든 예약어입니다

_foo

_엘

아닙니다. 소문자 앞에 선행 밑줄을 사용할 수없는 다른 상황이 있습니다. 필자의 경우 _L이 Visual C ++ 2005에 예약되어 있으며 충돌로 인해 예기치 않은 결과가 발생했습니다.

지역 변수를 표시하는 것이 얼마나 유용한 지 울타리에 있습니다.

다음은 예약 된 식별자에 대한 링크 입니다. C ++ 식별자에서 밑줄을 사용하는 규칙은 무엇입니까?


4
실제로 _foo와 _l은 네임 스페이스 범위에 예약되어 있습니다.

13
그러나 멤버 변수 이름으로는 괜찮습니다. 규칙이 너무 혼란스럽고 과거에 불에 타서 밑줄을 붙이지 않습니다.
Juan Juan

11
이들은 예약어가 아닙니다. 예약 된 이름입니다. 예약어 인 경우 전혀 사용할 수 없습니다. 그것들은 예약 된 이름이므로 사용할 수 있지만 자신의 책임은 귀하에게 있습니다.
TonyK

235

나는 모두 접두사 를 선호 합니다 .

나는 (시스템) 헝가리어 표기법이 접두사가 얻는 "나쁜 랩"의 대부분을 담당한다고 생각합니다.

이 표기법은 예를 들어 C ++ "lpsz"와 같이 강력하게 형식이 지정된 언어에서는 의미가 없습니다. 다음과 같은 경우 문자열이 널 종료 문자열에 대한 긴 포인터임을 나타냅니다. char 배열과 "customerName"이 문자열이라는 것을 알기 란 쉽지 않습니다!

그러나, 나는이 지정하는 데 사용할 접두사을 사용 (나는 그것 때문에 나쁜 및 시스템 헝가리어와 불공정 한 관계를 데 용어 헝가리어를 방지하는 것을 선호하지만, 본질적으로 "앱 헝가리어") 변수를,이 매우 편리 시간을 절약 하고 버그 감소 접근법.

나는 사용한다:

  • 회원의 경우 m
  • 상수 / 읽기 전용의 경우 c
  • 포인터의 경우 p (포인터의 포인터의 경우 pp)
  • 휘발성에 대한 v
  • 정적의 경우
  • 인덱스와 반복자의 경우
  • 이벤트의 경우 e

유형을 명확 하게하고 싶을 때는 표준 접미사 (예 : List, ComboBox 등)를 사용하십시오.

이를 통해 프로그래머 는 변수를 보거나 사용할 때마다 변수 의 사용법 을 알 수 있습니다. 아마도 가장 중요한 경우는 포인터에 대해 "p"입니다 (용법이 var.에서 var->로 변경되고 포인터 (Null, 포인터 산술 등)에 훨씬 더주의를 기울여야하기 때문에)이지만 다른 모든 것들은 매우 편리합니다.

예를 들어 단일 함수에서 동일한 변수 이름을 여러 방법으로 사용할 수 있습니다 (여기서는 C ++ 예제이지만 여러 언어에 동일하게 적용됨).

MyClass::MyClass(int numItems)
{
    mNumItems = numItems;
    for (int iItem = 0; iItem < mNumItems; iItem++)
    {
        Item *pItem = new Item();
        itemList[iItem] = pItem;
    }
}

당신은 여기에서 볼 수 있습니다 :

  • 멤버와 매개 변수가 혼동되지 않습니다
  • 인덱스 / 반복자와 아이템이 혼동되지 않습니다
  • "count", "index"와 같은 일반적인 (모호한) 이름의 많은 함정을 피하는 명확하게 관련된 변수 (항목 목록, 포인터 및 색인) 세트를 사용하십시오.
  • 접두어는 "itemIndex"및 "itemPtr"과 같은 대안보다 타이핑을 줄이고 (짧고 자동 완성 기능을 더 잘 수행합니다)

"iName"이터레이터의 또 다른 장점은 잘못된 인덱스로 배열을 인덱싱하지 않는다는 것입니다. 다른 루프 내에서 루프를 복사하면 루프 인덱스 변수 중 하나를 리팩터링 할 필요가 없습니다.

이 비현실적으로 간단한 예를 비교해보십시오.

for (int i = 0; i < 100; i++)
    for (int j = 0; j < 5; j++)
        list[i].score += other[j].score;

(읽기 어렵고 종종 "j"가 사용 된 곳에서 "i"를 사용하게 됨)

와:

for (int iCompany = 0; iCompany < numCompanies; iCompany++)
    for (int iUser = 0; iUser < numUsers; iUser++)
       companyList[iCompany].score += userList[iUser].score;

(이것은 훨씬 더 읽기 쉽고 인덱싱에 대한 모든 혼란을 제거합니다. 최신 IDE에서 자동 완성 기능을 사용하면 빠르고 쉽게 입력 할 수 있습니다)

다음 이점은 코드 스 니펫 이 컨텍스트 를 이해할 필요가 없다는 것입니다. 두 줄의 코드를 전자 메일이나 문서에 복사 할 수 있으며 해당 스 니펫을 읽는 사람은 모든 멤버, 상수, 포인터, 색인 등의 차이점을 알 수 있습니다. "아 추가 할 필요가 없습니다. 'data'는 포인터에 대한 포인터 '입니다. 왜냐하면'ppData '입니다.

같은 이유로, 나는 그것을 이해하기 위해 코드 라인에서 눈을 옮길 필요가 없습니다. 'data'가 로컬, 매개 변수, 멤버 또는 상수인지 확인하기 위해 코드를 검색 할 필요가 없습니다. 마우스로 손을 움직일 필요가 없으므로 '데이터'위에 포인터를 놓고 툴팁 (때로는 나타나지 않는)이 나타날 때까지 기다릴 수 있습니다. 따라서 프로그래머는 검색 및 검색 또는 대기 시간을 낭비하지 않기 때문에 코드를 훨씬 빠르게 읽고 이해할 수 있습니다 .

(물건을 찾기 위해 위아래로 검색하는 데 시간을 낭비하지 않는다고 생각되면 1 년 전에 작성했지만 이후에 보지 않은 코드를 찾으십시오. 파일을 열고 읽지 않고 반쯤 줄어 듭니다. 방법보기 무언가가 멤버, 매개 변수 또는 로컬인지 알기 전에이 시점에서 읽을 수 있습니다. 이제 임의의 다른 위치로 이동하십시오 ... 이것은 우리가 다른 사람의 코드를 한 번 밟을 때 하루 종일 모든 일을합니다. 또는 함수 호출 방법을 이해하려고 시도)

'm'접두어는 또한 (IMHO) 추악하고 말끔한 "this->"표기법과 그것이 보장하지 않는 일관성을 피합니다 (주의를 기울여도 'this-> data'와 동일한 클래스의 '데이터'는 이름의 일관된 철자를 강제하지 않습니다.

'이'표기법은 모호성 을 해결하기위한 것이지만 왜 모호 할 수있는 코드를 의도적으로 작성하는 사람이 있습니까? 모호성 조만간 버그로 이어질 입니다. 그리고 일부 언어에서는 'this'를 정적 멤버에 사용할 수 없으므로 코딩 스타일에 '특별한 경우'를 도입해야합니다. 나는 명시적이고 모호하지 않으며 일관된 모든 곳에 적용되는 하나의 간단한 코딩 규칙을 선호합니다.

마지막 주요 이점은 Intellisense 및 자동 완성 기능입니다. Windows Form에서 Intellisense를 사용하여 이벤트를 찾으십시오. 이벤트를 찾기 위해 호출 할 필요가없는 수백 가지의 신비한 기본 클래스 메소드를 스크롤해야합니다. 그러나 모든 이벤트에 "e"접두사가 있으면 "e"아래의 그룹에 자동으로 나열됩니다. 따라서 접두사는 지능 목록에서 멤버, const, 이벤트 등을 그룹화하여 원하는 이름을 훨씬 빠르고 쉽게 찾을 수 있도록합니다. (보통, 메소드에는 범위 내에서 액세스 할 수있는 약 20-50 개의 값 (로컬, 매개 변수, 멤버, const, 이벤트)이있을 수 있지만 접 두부를 입력 한 후 (지금 색인을 사용하고 싶습니다.) 'i. .. '), 2-5 개의 자동 완성 옵션 만 제공됩니다.

나는 게으른 프로그래머이고 위의 규칙은 많은 작업을 절약합니다. 모든 변수를 어떻게 사용해야하는지 알고 있기 때문에 더 빨리 코딩 할 수 있고 실수도 훨씬 줄어 듭니다.


반대론

그렇다면 단점은 무엇입니까? 접두사에 대한 일반적인 인수는 다음과 같습니다.

  • "접두사 계획은 / 악 나쁜" . 나는 "m_lpsz"와 그 ilk가 잘 생각되지 않고 완전히 쓸모 없다는 것에 동의합니다. 그렇기 때문에 상황에 맞지 않는 것을 복사하는 대신 요구 사항을 지원하도록 잘 설계된 표기법을 사용하는 것이 좋습니다. (작업에 맞는 도구를 사용하십시오).

  • "사용 방법을 변경하면 이름을 바꿔야합니다 . " 물론 리팩토링이 중요한 이유이며 IDE에이 작업을 빠르고 쉽게 수행 할 수있는 리팩토링 도구가있는 이유가 여기에 있습니다. 접두어가 없어도 변수의 사용법을 변경하면 이름 이 변경 되어야 합니다.

  • "접두사는 저를 혼동합니다" . 사용 방법을 익힐 때까지 모든 도구가 그러합니다. 당신의 두뇌가 네이밍 패턴에 익숙해지면, 정보를 자동으로 걸러 내고 접두사가 더 이상 존재하지 않을 것입니다. 그러나 실제로 "유창한"상태가되기 전에 1-2 주 동안 이와 같은 체계를 사용해야합니다. 그리고 많은 사람들이 오래된 코드를보고 좋은 접두사 체계 없이 어떻게 관리했는지 궁금해하기 시작합니다 .

  • "이 작업을 수행하는 코드 만 살펴볼 수 있습니다 . " 예, 그러나 코드의 다른 곳을 보거나 이미 눈에 초점을 맞춘 지점에 대한 답변이 올 바르면 모든 세부 사항을 기억하는 데 시간을 낭비하지 않아도됩니다.

  • (일부) 해당 정보는 툴팁이 내 변수에 나타날 때까지 기다리면 찾을 수 있습니다 . 예. 지원되는 경우 일부 접두사 유형의 경우 코드가 깨끗하게 컴파일 될 때 대기 후 설명을 읽고 접두사가 즉시 전달한 정보를 찾을 수 있습니다. 접두사가 더 간단하고 안정적이며 효율적인 방법이라고 생각합니다.

  • "더 많은 타이핑입니다" . 정말? 하나의 전체 문자 더? 또는 IDE 자동 완성 도구를 사용하면 각 접두사 문자가 검색 공간을 크게 좁히기 때문에 타이핑이 줄어드는 경우가 많습니다. "e"를 누르면 클래스의 세 가지 이벤트가 지능적으로 나타납니다. "c"를 누르면 5 개의 상수가 나열됩니다.

  • " this->대신에 사용할 수 있습니다 m" . 그래, 할 수있어 그러나 그것은 훨씬 더 추악하고 더 자세한 접두사입니다! 컴파일러에게는 선택 사항 이므로 사용법이 일관되지 않기 때문에 (특히 팀에서) 훨씬 큰 위험을 감수 합니다. m반면에 간단하고 명확하며 명시 적이며 선택 사항이 아니므로 실수로 사용하는 것이 훨씬 어렵습니다.


6
나는 헝가리어 표기법의 문제가 Simonyi가 오해했기 때문에 발생했다고 읽었습니다. 그는 리터럴 데이터 유형이 아니라 "종류"와 같이 "유형"을 의미하는 변수의 유형을 나타 내기 위해 접두사를 사용해야했습니다. 나중에 Microsoft의 플랫폼 담당자가 그것을 고르고 lpsz를 생각해 냈습니다. 나머지는 역사입니다 ...
직원

19
"s is static"은 헝가리어의 "나쁜"형식과 매우 흡사합니다.
jalf

6
@ Mehrdad : zC ++과 같은 언어에서는 저급 구현 세부 사항을 클래스로 캡슐화해야하지만 C (제로 종료가 중요한 구분)에서 당신에게 동의하는 경우가 종종 있다고 생각 합니다. IMO 우리가 사용하는 모든 체계는 우리 자신의 요구에 가장 잘 맞게 조정되어야합니다. 따라서 제로 종료가 변수 사용에 영향을 미치더라도 "z"를 유용한 접두사로 선언해도 아무 문제가 없습니다.
Jason Williams

14
The most important case is "p" for pointer (because the usage changes from var. to var-> and you have to be much more careful with pointers.나는 전적으로 동의하지 않습니다. 포인터를 잘못 사용하면 단순히 컴파일되지 않습니다 ( void*이중 포인터의 경우 예외 일 수 있음). 그리고 전체 ->이상은 .이 포인터입니다 말해 충분하다. 또한 자동 완성 기능을 사용하는 경우 편집기에 선언 툴팁이있을 수 있으므로 변수 정보 접두어를 사용할 필요가 없습니다. 어쨌든 좋은 대답입니다.
Thomas Eding

5
명확하고 포괄적이며 흥미로운 설명을지지하지만 C ++에서 시간을 절약하는 방법을 제안하는 것은 거의 없습니다.

115

나는 일반적으로 멤버 변수에 접두사를 사용하지 않습니다.

m"C ++에는 이미 회원 액세스를위한 표준 접두사가 있습니다."라고 지적 할 때까지 접두사 를 사용했습니다 this->.

이것이 제가 지금 사용하는 것입니다. 즉, 모호성이 있는 경우 this->접두사를 추가 하지만 일반적으로 모호성이 없으며 변수 이름을 직접 참조 할 수 있습니다.

나에게 그것은 두 세계의 최고입니다. 필요할 때 사용할 수있는 접두사가 있으며 가능할 때마다 그대로 둘 수 있습니다.

물론 이것에 대한 명백한 반대는 "그렇다. 그러나 변수가 클래스 멤버인지 아닌지를 한눈에 볼 수는 없다".

내가 "그렇게 무엇을 말해야합니까? 만약 당신이 그것을 알아야한다면, 당신의 클래스는 아마도 너무 많은 상태를 가질 것입니다. 또는 함수가 너무 크고 복잡합니다".

실제로, 나는 이것이 매우 잘 작동한다는 것을 알았습니다. 추가 보너스로 이름을 바꾸지 않고도 로컬 변수를 클래스 멤버 (또는 다른 방법)로 쉽게 승격시킬 수 있습니다.

그리고 무엇보다도 일관성이 있습니다! 일관성을 유지하기 위해 특별한 조치를 취하거나 규칙을 기억할 필요가 없습니다.


그건 그렇고, 당신 은해서는 안됩니다 반원에게 밑줄을 사용 . 구현에서 예약 한 이름에 불편하게 접근 할 수 있습니다.

표준은 이중 밑줄 또는 밑줄로 시작하고 뒤에 대문자로 된 모든 이름을 예약합니다. 또한 글로벌 네임 스페이스에서 단일 밑줄 시작하는 모든 이름을 예약합니다. .

따라서 밑줄과 소문자가 뒤 따르는 클래스 멤버는 합법적이지만 조만간 대문자로 시작하는 식별자와 동일하게하거나 위의 규칙 중 하나를 위반하게됩니다.

따라서 밑줄을 피하는 것이 더 쉽습니다. 변수 이름에 범위를 인코딩하려면 접두사 밑줄을 사용 m_하거나 m접두사를 사용하십시오 .


"따뜻한 밑줄과 소문자가있는 클래스 멤버는 합법적이지만 조만간 대문자로 시작하는 식별자와 동일하게하거나 위의 규칙 중 하나를 위반하게됩니다." -클래스 멤버 변수는 전역 네임 스페이스에 없으므로 소문자 또는 대문자와 관계없이 선행 밑줄이 안전합니다.
mbarnett

3
@mbarnett : 아니요, 밑줄과 대문자는 전역 네임 스페이스뿐만 아니라 일반적으로 예약 되어 있습니다.
jalf

9
이 답변의 투표가 접두사보다 작다는 것에 놀랐습니다.
Marson Mao

이 답변에 동의합니다 this->. 구성원 변수를 지정해야하거나 그렇지 않은 경우에도 사용하십시오.
David Morton

또한 다른 사람들에게 코드를 제공하기 위해 컨벤션을 문서화 할 필요가 없습니다. 모두가 무슨 this->뜻 인지 이해 합니다.
Caduchon

34

다음과 같이 접미사 밑줄을 선호합니다.

class Foo
{
   private:
      int bar_;

   public:
      int bar() { return bar_; }
};

나도. 또한 접근 자 / 돌연변이에게 같은 이름을 부여합니다.
Rob

4
흥미 롭군 처음에는 조금 못 생겼지 만 그것이 어떻게 유익 할 수 있는지 알 수 있습니다.
ya23

6
"mBar"또는 "m_bar"보다 훨씬 덜 추악하다고 말하고 싶습니다.
sydan

6
그러나 당신은 가지고 vector<int> v_;있고 쓰기 v_.push_back(5)도 꽤 추악합니다
avim

4
이것이 Google C ++ 스타일입니다.
Justme0

20

최근 접두사가없는 대신 m_ 접두사를 선호하는 경향이 있었기 때문에 그 이유는 멤버 변수를 플래그 지정하는 것이 중요하지 않지만 모호성을 피하기 위해 다음과 같은 코드가 있다고합니다.

void set_foo(int foo) { foo = foo; }

원인은 효과가 없으며 하나만 foo허용됩니다. 옵션은 다음과 같습니다.

  • this->foo = foo;

    매개 변수 섀도 잉을 유발하므로 더 이상 g++ -Wshadow경고 를 사용할 수 없으며 더 이상 입력하지 않아도 m_됩니다. 또한 a int foo;와 a 가있을 때 변수와 함수 사이의 이름 충돌이 계속 발생 합니다 int foo();.

  • foo = foo_; 또는 foo = arg_foo;

    잠시 동안 그것을 사용했지만 인수 목록을 추악하게 만들었습니다. 문서는 구현에서 이름 모호성을 다루지 않아야합니다. 변수와 함수 사이의 이름 충돌도 여기에 존재합니다.

  • m_foo = foo;

    API 설명서는 깨끗하게 유지되므로 멤버 함수와 변수 사이에 모호함이 없으며 입력하기가 더 짧습니다 this->. 단점은 POD 구조를 추악하게 만든다는 것입니다. 그러나 POD 구조는 애매 모호성으로 인해 어려움을 겪지 않기 때문에 POD 구조를 사용할 필요가 없습니다. 고유 한 접두사를 사용하면 검색 및 교체 작업이 더 쉬워집니다.

  • foo_ = foo;

    m_적용 의 장점의 대부분은 미학적 이유로 거부하지만, 밑줄 또는 선행 밑줄은 변수를 불완전하고 불균형으로 보이게합니다. m_더 좋아 보인다. 전역 및 정적에 m_사용할 수 있으므로 사용 이 더 확장 가능 합니다.g_s_

추신 : m_파이썬이나 루비에서 보이지 않는 이유 는 두 언어가 모두 자신의 접두사를 시행하고 루비가 @멤버 변수에 사용 하기 때문에 파이썬은 필요합니다 self..


1
박람회로, 당신은 적어도 2 다른 옵션을 놓친 예를 들어 (가)처럼 전체 이름을 사용하는 foo경우에만 회원 대신 단일 문자 또는 매개 변수 나 같은 다른 주민 / throwaways, 짧은 이름을 사용 int f; 또는 (b) 매개 변수 나 다른 지역에 접두사를 붙인다 . 좋은 점 re m_와 꼬투리; 나는 독립적으로 그 두 가지 지침을 모두 따르기를 선호합니다.
underscore_d

12

멤버 함수를 통해 읽을 때 변수의 의미를 이해하려면 각 변수를 "소유"하는 사람을 알아야합니다. 이 같은 기능에서 :

void Foo::bar( int apples )
{
    int bananas = apples + grapes;
    melons = grapes * bananas;
    spuds += melons;
}

사과와 바나나가 어디에서 나오는지 알기 쉽지만 포도, 멜론, 스퍼 드는 어떻습니까? 전역 네임 스페이스를 살펴 봐야합니까? 수업 선언에서? 변수가이 객체의 멤버입니까 아니면이 객체 클래스의 멤버입니까? 이러한 질문에 대한 답을 모르면 코드를 이해할 수 없습니다. 그리고 더 긴 기능에서 사과와 바나나와 같은 지역 변수 선언도 셔플에서 사라질 수 있습니다.

전역 변수, 멤버 변수 및 정적 멤버 변수 (각각 g_, m_ 및 s_)에 대해 일관된 레이블을 추가하면 상황이 즉시 명확 해집니다.

void Foo::bar( int apples )
{
    int bananas = apples + g_grapes;
    m_melons = g_grapes * bananas;
    s_spuds += m_melons;
}

처음에는 익숙해 져야 할 수도 있습니다. 그러나 프로그래밍에서 그렇지 않은 것은 무엇입니까? {와}조차 당신에게 이상하게 보였던 하루가있었습니다. 그리고 일단 익숙해지면 코드를 훨씬 빨리 이해하는 데 도움이됩니다.

(m_ 대신 "this->"를 사용하는 것은 의미가 있지만 훨씬 더 오래 걸리고 시각적으로 파괴적입니다. 멤버 변수의 모든 용도를 표시하는 좋은 대안으로 생각하지는 않습니다.)

위의 인수에 대한 가능한 반대는 인수를 유형으로 확장하는 것입니다. 변수의 유형을 아는 것이 변수의 의미를 이해하는 데 절대적으로 필요하다는 것도 사실 일 수 있습니다. 그렇다면 유형을 식별하는 각 변수 이름에 접두사를 추가하지 않겠습니까? 이 논리를 사용하면 헝가리 표기법으로 끝납니다. 그러나 많은 사람들은 헝가리어 표기가 힘들고 못 생겼으며 도움이되지 않는다고 생각합니다.

void Foo::bar( int iApples )
{
    int iBananas = iApples + g_fGrapes;
    m_fMelons = g_fGrapes * iBananas;
    s_dSpuds += m_fMelons;
}

헝가리어 않습니다코드에 대해 새로운 것을 알려주세요. 이제 Foo :: bar () 함수에 여러 암시 적 캐스트가 있음을 이해합니다. 코드의 문제점은 헝가리 접두사가 추가 한 정보의 가치가 시각적 비용에 비해 작다는 것입니다. C ++ 유형 시스템에는 유형이 함께 작동하거나 컴파일러 경고 또는 오류를 발생시키는 데 도움이되는 많은 기능이 포함되어 있습니다. 컴파일러는 타입을 다루는 데 도움을줍니다. 표기 할 필요는 없습니다. Foo :: bar ()의 변수가 숫자 일 수 있다는 것을 쉽게 추론 할 수 있습니다. 이것이 우리가 아는 한, 함수에 대한 일반적인 이해를 얻는 데 충분합니다. 따라서 각 변수의 정확한 유형을 아는 값은 상대적으로 낮습니다. 그러나 "s_dSpuds"(또는 "dSpuds")와 같은 변수의 추함은 훌륭합니다. 그래서,


s_ 아이디어 주셔서 감사합니다. 매우 유용한 것으로 보이며, 어떻게 든 나에게 결코 발생하지 않았습니다.
Chris Olsen

10

나는 그것이 얼마나 널리 퍼져 있는지 말할 수는 없지만 개인적으로 말하면 항상 멤버 변수 앞에 항상 'm'을 붙였습니다. 예 :

class Person {
   .... 
   private:
       std::string mName;
};

그것은 내가 사용하는 접두사의 유일한 형태입니다 (나는 매우 헝가리어 표기법입니다). 따로, 나는 일반적으로 이름 (또는 그 문제에 대한 다른 곳)에서 밑줄 사용을 비난하지만 전 처리기 매크로 이름은 일반적으로 모두 대문자이므로 예외를 만듭니다.


5
m_ (또는 _) 대신 m을 사용하는 문제는 낙타의 경우 현재 유행 방식으로 인해 일부 변수 이름을 읽기가 어렵습니다.
Martin Beckett

1
@Neil 나는 당신과 함께 있습니다. @mgb : '_'로 시작하는 이름이 싫습니다. 그것은 미래에 잘못 될 수있는 초대입니다.
Martin York

1
@Neil : 밑줄을 사용하지 않고 낙타를 사용하지 않으면 어떤 규칙을 사용합니까?
jalf

2
내 이해는 'apData'와 같은 변수에 m을 사용하여 혼란스럽게하는 것은 camelCase라는 것입니다 .'m_apData '가 아닌'mapData '가됩니다. 그것이 눈에 띄는 때문에 보호 / private 멤버 변수에 대한 _camelCase를 사용
마틴 베켓을

10
@MartinBeckett : a해당 시나리오에서 대문자를 사용해야합니다 . 그렇지 않으면 제대로 수행하지 않는 것입니다. mApData(m 접두사, 변수 이름은 apData)입니다.
Platinum Azure

8

멤버 접두사의 주된 이유는 멤버 함수 로컬과 이름이 같은 멤버 변수를 구별하기위한 것입니다. 이것은 물건의 이름으로 게터를 사용할 때 유용합니다.

치다:

class person
{
public:
    person(const std::string& full_name)
        : full_name_(full_name)
    {}

    const std::string& full_name() const { return full_name_; }
private:
    std::string full_name_;
};

이 경우 멤버 변수를 full_name (으)로 호출 할 수 없습니다. 멤버 함수의 이름을 get_full_name ()으로 바꾸거나 멤버 변수를 어떻게 든 장식해야합니다.


1
이것이 내가 접두사 인 이유입니다. 내 생각 foo.name()보다 훨씬 더 읽기 쉽다고 생각 foo.get_name()합니다.
Terrabits

6

한 구문이 다른 구문보다 실제 가치가 있다고 생각하지 않습니다. 언급했듯이 소스 파일 전체에서 균일 성이 떨어집니다.

내가 그런 규칙을 흥미롭게 생각하는 유일한 점은, 같은 이름의 두 가지가 필요할 때입니다.

void myFunc(int index){
  this->index = index;
}

void myFunc(int index){
  m_index = index;
}

나는 그것을 두 가지를 구별하기 위해 사용합니다. 또한 나는 DLL을, 윈도우에서처럼 전화를 포장 할 때 RecvPacket (...) DLL에서가에 싸여 수 있습니다 RecvPacket (...) 내 코드에서. 이러한 특별한 경우 "_"와 같은 접두사를 사용하면 두 가지를 비슷하게 보이게 만들 수 있습니다.


6

일부 응답은 가독성을 향상시키는 방법으로 명명 규칙 대신 리팩토링에 중점을 둡니다. 나는 하나가 다른 하나를 대신 할 수 있다고 생각하지 않습니다.

지역 선언을 사용하는 것이 불편한 프로그래머를 알고 있습니다. 그들은 모든 선언을 블록 상단에 배치하는 것을 선호하므로 (C와 같이) 어디에서 찾을 수 있는지 알고 있습니다. 범위 지정이 허용되는 경우 변수가 처음 사용되는 위치를 선언하면 선언을 찾기 위해 뒤로 거꾸로 쓰는 데 걸리는 시간이 줄어 듭니다. (이것은 작은 기능에도 적용됩니다.) 그러면 내가보고있는 코드를 더 쉽게 이해할 수 있습니다.

이것이 멤버 이름 지정 규칙과 어떻게 관련되어 있는지 분명히 알 수 있기를 바랍니다. 소스 파일에서도 선언을 찾을 수 없다는 것을 알고 있습니다.

나는 이러한 스타일을 선호하기 시작하지 않았다고 확신합니다. 그러나 시간이 지남에 따라 일관되게 사용되는 환경에서 일하면서 나는 그것들을 활용하기 위해 내 생각을 최적화했습니다. 나는 현재 그들에게 불편 함을 느끼는 많은 사람들이 일관된 사용법으로 그들을 선호하게 될 가능성이 있다고 생각합니다.


5

이러한 규칙은 바로 그 것입니다. 대부분의 상점은 코드 규칙을 사용하여 코드를 쉽게 읽을 수 있으므로 누구나 쉽게 코드를보고 공용 및 개인 구성원과 같은 항목을 빠르게 해독 할 수 있습니다.


"공공 및 개인 회원과 같은 것들 사이"-이것이 얼마나 흔한 일입니까? 나는 그것을 본 것을 기억하지 않지만 다시 한 번 코드베이스 또는 다른 것을 검토하지는 않습니다.
underscore_d

나는 내 코딩으로하지 않지만 코드 컨벤션 가이드를 기반으로 해야하는 곳에서 일했습니다. 거의 모든 IDE가 개인 변수에 다른 색상을 표시하므로 사용하지 않는 것이 좋습니다.
Mr. Will은

흠, 나는 그것이 내 상황과 다른 상황에서만 발생한다고 생각합니다. 일반적으로 나는 class멤버가 모두 private/ 인 es protected또는 struct변수가 모두 public(및 종종 const) 인 POD 를 사용합니다 . 따라서 특정 멤버의 액세스 수준에 대해 궁금 할 필요가 없습니다.
underscore_d

5

다른 사람들은 멤버 변수가 사용될 때마다 this-> member를 사용하려고합니다.

일반적으로 접두사가 없기 때문입니다 . 컴파일러는 문제의 변수를 해결하기 위해 충분한 정보가 필요합니다. 접두사 때문에 고유 한 이름이거나this 키워드 .

예, 접두사가 여전히 유용하다고 생각합니다. 나는 'this->'보다는 멤버에 액세스하기 위해 '_'를 입력하는 것을 선호합니다.


3
컴파일러는 어쨌든 그것을 해결할 수 있습니다 ... 지역 변수는 대부분의 언어에서 더 높은 범위의 변수를 숨길 것입니다. 그것은 코드를 읽는 인간의 (의심스러운) 이익을위한 것입니다. 괜찮은 IDE라면 로컬 / 멤버 / 글로벌을 다른 방식으로 강조 할 것이므로 이런 종류의 물건이 필요하지 않습니다
rmeador

1
바로 그거죠. 지역 주민들은 반원들을 숨길 것입니다. 이러한 멤버를 설정하는 생성자를 고려하십시오. 일반적으로 매개 변수 이름을 멤버와 동일하게 지정하는 것이 좋습니다.
Kent Boogaart

6
왜 코드 냄새가 나나요? 특히 생성자에 관해서는 완벽하고 일반적이며 합리적이라고 말하고 싶습니다.
Kent Boogaart

3
생성자는 (일반적으로) 초기화 목록에 로컬을 설정해야합니다. 그리고 거기에서, 매개 변수는 필드 이름 struct Foo { int x; Foo(int x) : x(x) { ... } };
Pavel Minaev

2
Foo(int x, bool blee) : x(x) { if (blee) x += bleecount; } // oops, forgot this->멤버 변수를 유용한 것으로 부르고 축약 된 이름과 일치하는 생성자 매개 변수 를 제공 할 때 문제가 발생한다고 가정합니다 .Foo(int f) : foo(f) {...}
Steve Jessop

4

다른 언어는 코딩 규칙을 사용하지만 다른 경향이 있습니다. 예를 들어 C #에는 사람들이 자주 사용하는 두 가지 스타일, 즉 C ++ 메서드 (_variable, mVariable 또는 헝가리어 표기법과 같은 다른 접두사) 또는 내가 StyleCop 메서드라고하는 다른 스타일이 있습니다.

private int privateMember;
public int PublicMember;

public int Function(int parameter)
{
  // StyleCop enforces using this. for class members.
  this.privateMember = parameter;
}

결국 사람들이 아는 것과 가장 잘 보이는 것이됩니다. 개인적으로 코드는 헝가리어 표기법 없이도 읽을 수 있다고 생각하지만 헝가리어 표기법이 첨부되어 있으면 지능적으로 변수를 찾기가 더 쉬워 질 수 있습니다.

위의 예제에서는 사용법을 접두어로 사용하므로 멤버 변수에 m 접두사가 필요하지 않습니다. 컴파일러 적용 방법에서 동일한 것을 나타냅니다.

이것은 반드시 다른 방법이 나쁘다는 것을 의미하지는 않습니다. 사람들은 작동하는 것을 고수합니다.


3

메서드 나 코드 블록이 크면 지역 변수 나 멤버를 사용하는지 즉시 알 수 있습니다. 오류를 피하고 명확성을 높이는 것입니다!


3
당신이 큰 방법을 가지고 있다면, 더 나은 명확성을 위해 그것을 분해하십시오.
sbi

4
큰 방법을 분해하지 않는 데는 많은 이유가 있습니다. 예를 들어, 메소드가 많은 로컬 상태를 유지해야하는 경우, 많은 메소드를 종속 메소드에 전달하거나 이러한 메소드간에 데이터를 전달하기위한 목적으로 만 존재하는 새 클래스를 작성하거나 상태 데이터를 다음과 같이 선언해야합니다. 부모 클래스의 멤버 데이터 이 모든 것들은 하나의 긴 방법 (특히 논리가 간단한 방법)과 비교하여 방법의 명확성이나 유지 관리성에 영향을 미치는 문제가 있습니다.
Steve Broberg

3
@ sbi : 지침은 바로 그 것입니다. 규칙이 아닌 지침. 때로는 논리적으로 분리되지 않는 큰 메소드가 필요하며 때로는 매개 변수 이름이 멤버와 충돌합니다.
Ed S.

멤버 변수를 공개하지 마십시오. 접근자를 사용하십시오. 괄호는 독자에게 그것이 멤버 변수라는 것을 알려줘야합니다.
jkeys

gcc (> = 4.6)에는 이름의 충돌을 감지하는 경고가 있습니다.-Wshadow
Caduchon

3

IMO, 이것은 개인입니다. 접두사를 전혀 쓰지 않습니다. 어쨌든 코드가 공개되어야한다는 의미라면 접두사가 더 있어야하므로 더 읽기 쉽습니다.

대기업은 종종 '개발자 규칙'이라고하는 자체 개발 도구를 사용합니다.
Btw, 내가 본 가장 재미 있고 똑똑한 것은 DRY KISS (자신을 반복하지 마십시오. 간단하게 유지하십시오). :-)


3

다른 사람들이 이미 말했듯이, 중요성은 구어체 (작성하는 코드베이스에 명명 스타일과 규칙을 적용)와 일관성을 유지하는 것입니다.

몇 년 동안 나는 "this->"규칙과 postfix를 모두 사용하는 큰 코드 기반 작업을 해왔다 멤버 변수에 대한 밑줄 표기법을 . 지난 몇 년 동안 저는 소규모 프로젝트를 진행해 왔는데, 그 중 일부는 멤버 변수 이름 지정 규칙이 없었고 다른 하나는 멤버 변수 이름 지정 규칙이 다릅니다. 그 작은 프로젝트 중에서도 컨벤션이 부족한 프로젝트를 빠르게 이해하고 이해하기가 가장 어렵다는 것을 지속적으로 발견했습니다.

나는 이름에 대해 매우 항문을 가지고 있습니다. 클래스 나 변수에 속하게 될 이름에 대해 고민하고, "좋은"느낌이 드는 것을 발견 할 수없는 경우, 말도 안되는 이름을 지정하고 실제로 무엇을 설명하는 주석을 제공 할 것입니다 입니다. 그런 식으로, 적어도 그 이름은 내가 의미하는 바를 의미합니다. 그리고 종종, 잠시 동안 사용한 후에, 나는 그 이름이 실제로 무엇이고, 되돌아 가서 적절하게 수정하거나 리팩토링 할 수 있는 것을 발견합니다 .

IDE가 작업을 수행하는 주제에 대한 마지막 요점은 모두 훌륭하지만 훌륭합니다.하지만 가장 긴급한 작업을 수행 한 환경에서는 IDE를 종종 사용할 수 없습니다. 때때로 그 시점에서 사용 가능한 유일한 것은 'vi'의 사본입니다. 또한 IDE 코드 완성이 잘못된 철자 이름과 같은 어리 석음을 전파하는 경우를 많이 보았습니다. 따라서 IDE 목발에 의존하지 않아도됩니다.


3

C ++ 멤버 변수의 접두사에 대한 원래 아이디어는 컴파일러가 알지 못하는 추가 유형 정보를 저장하는 것이 었습니다. 예를 들어 고정 길이의 문자 인 문자열과 변수가 있고 '\ 0'으로 끝나는 문자열을 가질 수 있습니다. 컴파일러 char *에게는 둘 다 이지만 하나에서 다른 것으로 복사하려고하면 큰 문제가 발생합니다. 머리 꼭대기에서

char *aszFred = "Hi I'm a null-terminated string";
char *arrWilma = {'O', 'o', 'p', 's'};

여기서 "asz"는이 변수가 "ascii string (0-terminated)"이고 "arr"는이 변수가 문자 배열임을 의미합니다.

그러면 마법이 일어납니다. 컴파일러는 다음 문장에 매우 만족합니다.

strcpy(arrWilma, aszFred);

그러나 당신은 인간으로서 그것을보고 "이봐 요, 그 변수들은 실제로 같은 유형이 아니에요, 그렇게 할 수 없습니다"라고 말할 수 있습니다.

불행히도 많은 경우 멤버 변수의 경우 "m_", 정수의 경우 "i", 문자의 경우 "cp"와 같은 표준을 사용합니다. 즉, 컴파일러가 알고있는 내용을 복제하고 동시에 코드를 읽기 어렵게 만듭니다. 본인은이 악의적 인 관행이 법령에 의해 금지되고 엄격한 처벌을 받아야한다고 생각합니다.

마지막으로 언급해야 할 두 가지 사항이 있습니다.

  • C ++ 기능을 신중하게 사용하면 컴파일러가 원시 C 스타일 변수로 인코딩해야하는 정보를 알 수 있습니다. 유효한 작업 만 허용하는 클래스를 만들 수 있습니다. 이것은 실용적이어야합니다.
  • 코드 블록이 너무 오래 당신이 잊어 경우 당신이 그것을 사용하기 전에 어떤 변수를 입력하는 것은 그들이 인 방법 너무 오래. 이름을 사용하지 말고 재구성하십시오.

변수의 유형이나 종류를 나타내는 접두사도 토론 할 가치가 있지만, 주로 (비공개) 멤버 / 필드인지를 나타내는 접두사를 언급하고있었습니다. 언급 한 역 헝가리어 표기법은 지능적으로 적용될 때 (예와 같이) 매우 유용 할 수 있습니다. 내가 가장 좋아하는 예는 상대 좌표와 절대 좌표입니다. absX = relX가 표시되면 무언가 잘못되었을 수 있음을 알 수 있습니다. 함수 이름도 적절하게 지정할 수 있습니다. absX = absFromRel (relX, offset);
VoidPointer

참고 : aszFred의 초기화는 의문의 여지가 있으며 (리터럴 문자열에 대한 비 const 액세스 제공) arrWilma의 초기화는 컴파일되지 않습니다. (당신은 아마 포인터 대신, 배열로 arrWilma을 선언하도록하지!) 그래도 아무 문제가, 당신은 당신의 머리 위로 떨어져이 있다고 쓴 ... :-)
닐스 데커

죄송합니다. 아이들, 집에서 시도하지 마십시오. 'const char * aszFred = "안녕하세요. null로 끝나는 문자열입니다."; char arrWilma [] = { 'O', 'o', 'p', 's'}; '
AL Flanagan

3

우리 프로젝트는 항상 "its"를 멤버 데이터의 접두사로 사용하고 "the"를 매개 변수의 접두사로 사용했습니다. 약간 귀엽지 만, 우리 시스템의 초기 개발자가 우리가 사용했던 일부 상용 소스 라이브러리 (XVT 또는 RogueWave 중 하나 또는 둘 다)의 규칙으로 사용되기 때문에 시스템의 초기 개발자가 채택했습니다. 따라서 다음과 같은 것을 얻을 수 있습니다.

void
MyClass::SetName(const RWCString &theName)
{
   itsName = theName;
}

접두어 범위를 지정하고 다른 언어를 사용하지 않는 가장 큰 이유는 헝가리어 표기법을 싫어합니다. 한 변수를 참조한다고 생각되는 코드를 작성하여 문제가 발생하지 않도록하지만 실제로는 다른 변수를 참조하기 때문입니다 로컬 범위에 동일한 이름으로 정의되어 있습니다. 또한 동일한 개념을 나타 내기 위해 변수 이름이 나오지 만 위의 예와 같이 범위가 다른 문제를 피합니다. 이 경우 어쨌든 매개 변수 "theName"에 대해 접두사 또는 다른 이름을 사용해야합니다. 왜 모든 곳에 적용되는 일관된 규칙을 작성하지 않겠습니까?

이것을 사용하는 것만으로는 충분하지 않습니다. 코딩 오류를 줄이는 것처럼 모호성을 줄이는 데 관심이 없으며 로컬 범위 식별자로 이름을 마스킹하는 것이 어려울 수 있습니다. 물론 일부 컴파일러에는 이름을 더 큰 범위로 숨긴 경우 경고를 발생시킬 수있는 옵션이 있지만 선택한 타사 라이브러리 세트로 작업하는 경우 경고가 성 가실 수 있습니다. 가끔 자신과 충돌하는 사용하지 않는 변수의 이름.

그 자체에 관해서는-솔직히 밑줄보다 타이핑하는 것이 더 쉽다는 것을 알았습니다 (터치 타이피스트로서 가능한 한 밑줄을 너무 많이 피하십시오).


이것은 내가 들어 본 가장 빠른 학습 곡선을 가진 가장 직관적 인 솔루션입니다. 음성 언어가 모든 언어를보다 유연하게 처리 할 수 ​​있기를 원하므로 코드의 모호성을 해결하기 위해 새로운 기술을 생각 해낼 필요가 없었습니다.
Guney Ozsan

2

VC ++의 Intellisense가 클래스 외부에서 액세스 할 때 개인 구성원을 언제 표시 해야하는지 알 수 없기 때문에 사용합니다. 유일한 표시는 Intellisense 목록의 필드 아이콘에 작은 "잠금"기호입니다. 개인 멤버 (필드)를보다 쉽게 ​​식별 할 수 있습니다. 또한 C #의 습관은 정직합니다.

class Person {
   std::string m_Name;
public:
   std::string Name() { return m_Name; }
   void SetName(std::string name) { m_Name = name; }
};

int main() {
  Person *p = new Person();
  p->Name(); // valid
  p->m_Name; // invalid, compiler throws error. but intellisense doesn't know this..
  return 1;
}

2

클래스 멤버를 멤버 함수 매개 변수 및 로컬 변수와 구별하기 위해 접두사가 필요한 경우 함수가 너무 크거나 변수의 이름이 잘못되었습니다. 화면에 맞지 않으면 무엇을 쉽게 볼 수 있는지 리팩토링하십시오.

그것들이 종종 그들이 사용되는 곳과는 거리가 멀다는 것을 감안할 때 전역 상수 (및 전역 변수, IMO를 사용할 필요는 거의 없지만)에 대한 명명 규칙이 의미가 있음을 알았습니다. 그러나 그렇지 않으면 나는 많은 필요를 보지 못합니다.

즉, 나는 모든 개인 반원의 끝에 밑줄을 썼다. 내 모든 데이터는 개인 정보이므로 회원에게는 밑줄이 있습니다. 나는 보통 새로운 코드베이스에서 더 이상 이것을하지 않지만 프로그래머로서 대부분 오래된 코드로 작업하기 때문에 여전히이 작업을 많이 수행합니다. 나는이 습관에 대한 나의 관용이 내가 이것을 항상 사용하고 여전히 규칙적으로하고 있다는 사실 또는 멤버 변수의 표시보다 실제로 더 의미가 있는지에 대해 확신하지 못합니다.


2
이것은이 문제에 대한 나의 느낌을 반영합니다. 접두사를 사용하지 않고 코드를 읽을 수 있어야합니다. 어쩌면 우리는 사용자 커뮤니티가 때때로 C ++에서 보는 것보다 약간 더 많은 가독성을 수용했기 때문에 더 현대적인 언어에서 접두어 사용이 많지 않을 수도 있습니다. 물론 C ++는 읽을 수 있고 읽을 수 있어야합니다. 수년 동안 읽을 수없는 많은 C ++이 작성되었다는 것입니다.
VoidPointer


1

메모리 관리로 인해 멤버 변수와 로컬 변수를 구별하는 것이 유용합니다. 일반적으로 힙 할당 멤버 변수는 소멸자에서 삭제해야하며 힙 할당 로컬 변수는 해당 범위 내에서 삭제해야합니다. 멤버 변수에 이름 지정 규칙을 적용하면 올바른 메모리 관리가 용이 ​​해집니다.


어떻게 요? 소멸자는 다른 함수에서 선언 된 지역 변수에 액세스 할 수 없으므로 혼동의 여지가 없습니다. 게다가 힙 할당 로컬 변수 는 존재하지 않아야합니다 . 힙 할당 멤버 변수는 RAII 클래스 내부에만 존재해야합니다.
jalf

"힙 할당 된 로컬 변수는 존재하지 않아야합니다"는 약간 강력합니다. 그러나 당신이 그것들을 사용할 때, 그것이 중요하게 할당 해제되도록하는 것이 매우 중요합니다. 따라서 멤버 대 로컬 변수에 대한 규명 된 명명 규칙은 이것을 보장하는 데 절대적으로 도움이됩니다.
frankster

1

Code Complete는 멤버 변수에 m_varname을 권장합니다.

m_ 표기법이 유용하다고 생각하지는 않았지만 표준을 세우는 데있어 McConnell의 견해를 중요시합니다.


2
왜 밑줄을 설명하지 않는 한 아닙니다. 나는 그의 "신속한 개발"책의 열렬한 팬인데, 여기에서 여러 번 추천했지만 "코드 완성"(훨씬 처음 나온 이후로 읽지 않았 음)은 훨씬 적습니다.

1

변수 이름 앞에 접두사를 거의 사용하지 않습니다. 적절한 IDE를 사용하고 있다면 리팩터링하고 참조를 쉽게 찾을 수 있어야합니다. 나는 매우 명확한 이름을 사용하고 긴 변수 이름을 갖는 것을 두려워하지 않습니다. 이 철학으로 범위에 문제가 없었습니다.

접두사를 사용하는 유일한 시간은 서명 줄에 있습니다. 매개 변수 앞에 _를 사용하여 메서드 앞에 접두사를 붙여 방어 적으로 프로그래밍 할 수 있습니다.


1

그런 접두사가 필요하지 않습니다. 그러한 접두어가 어떤 이점을 제공한다면 일반적으로 코딩 스타일을 수정해야하며 코드가 명확하지 않은 접두사가 아닙니다. 일반적으로 잘못된 변수 이름에는 "other"또는 "2"가 있습니다. mOther가되도록 요구하지 말고 개발자가 해당 함수의 맥락에서 해당 변수가 무엇을하고 있는지 생각하게하여 수정하십시오. 아마도 그는 remoteSide 또는 newValue 또는 secondTestListener 또는 해당 범위의 무언가를 의미했을 것입니다.

여전히 너무 멀리 전파 된 효과적인 구식입니다. 변수 접두사를 멈추고 사용 기간을 명확하게 나타내는 적절한 이름을 지정하십시오. 최대 5 줄을 혼동하지 않고 "i"라고 부를 수 있습니다. 50 줄 이상이면 꽤 긴 이름이 필요합니다.


1

변수 이름이 포함 된 값에만 의미를 부여하고 변수 이름이 선언 / 구현되는 방식을 그대로 둡니다. 가치의 의미, 기간을 알고 싶습니다. 아마도 평균 리팩토링 이상을 수행했을 수도 있지만 이름에 무언가가 구현되는 방식을 포함 시키면 리팩토링이 필요 이상으로 지루하다는 것을 알았습니다. 객체 멤버가 선언되는 위치 또는 방법을 나타내는 접두사는 구현에 따라 다릅니다.

color = Red;

대부분의 경우 Red가 열거 형인지 구조 체인지 여부는 신경 쓰지 않으며 함수가 너무 커서 색상이 로컬로 선언되었거나 멤버인지 기억할 수없는 경우 아마도 깨질 시간입니다. 더 작은 논리 단위로 기능.

순환 적 복잡성이 너무 커서 사물 이름에 구현 관련 단서가없는 코드에서 진행중인 작업을 추적 할 수없는 경우 함수 / 방법의 복잡성을 줄여야합니다.

주로 생성자와 이니셜 라이저에서만 'this'를 사용합니다.


0

Intellisense 및 관련 IDE 기능을 활용하기 위해 멤버 변수에 m_을 사용합니다. 클래스 구현을 코딩 할 때 m_을 입력하고 모든 m_ 멤버가 함께 그룹화 된 콤보 상자를 볼 수 있습니다.

그러나 물론 문제없이 m_없이 살 수있었습니다. 그것은 단지 내 작업 스타일입니다.


다음을 입력 할 수도 있습니다this->
Toast

0

조인트 스트라이크 파이터 에어 차량 C ++ 코딩 표준 (2005 년 12 월)에 따르면 :

AV 규칙 67

공개 및 보호 된 데이터는 클래스가 아닌 구조체에만 사용해야합니다. 이론적 근거 : 클래스는 데이터에 대한 액세스를 제어하여 불변성을 유지할 수 있습니다. 그러나 개인이 아닌 개인의 클래스는 구성원에 대한 액세스를 제어 할 수 없습니다. 따라서 클래스의 모든 데이터는 개인용이어야합니다.

따라서 "m"접두사는 모든 데이터가 개인용이어야하므로 사용할 수 없게됩니다.

그러나 p 접두사를 위험한 변수이므로 포인터 앞에 사용하는 것이 좋습니다.


0

이러한 규칙 중 상당수는 정교한 편집자가없는 시대부터 시작되었습니다. 모든 종류의 변수에 색상을 지정할 수있는 적절한 IDE를 사용하는 것이 좋습니다. 접두사보다 색상을 훨씬 쉽게 찾을 수 있습니다.

변수에 대해 더 자세히 알아야 할 경우 최신 IDE는 캐럿이나 커서를 움직여 변수를 보여줄 수 있어야합니다. 그리고 변수를 잘못된 방식으로 사용하면 (예 :. 연산자가있는 포인터) 어쨌든 오류가 발생합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.