가독성이 (참조) 매개 변수에서 const를 사용하지 않는 유효한 이유입니까?


24

일부 함수를 작성할 때 다음과 같은 매개 변수에서 const 키워드를 찾았습니다.

void MyClass::myFunction(const MyObject& obj,const string& s1,const string& s2,const string& s3){
}

종종 IDE 또는 vim에서 한 줄을 두 줄로 나누기 때문에 매개 변수에서 모든 const 키워드를 제거하고 싶습니다.

void MyClass::myFunction(MyObject& obj,string& s1,string& s2,string& s3){
} 

const를 사용하지 않는 유효한 이유입니까? 매개 변수 개체를 수동으로 변경하지 않고 유지할 수 있습니까?


110
프로그램을 더 읽기 쉽게하기 위해 "프로그램을 기능적으로 변경하고 싶습니다"는 나쁜 나쁜 이유입니다.
Pieter B

37
프로그램은 더 이상 읽을 수 없게됩니다. 일단 무언가가 넘겨지는 것을 보았을 const때 함수에서 어떻게 변경 될 수 있는지에 대한 강력한 힌트가 필요합니다.
tofro

43
가독성을 향상시키는 더 좋은 방법 은 인수 줄이는 것입니다 .
5gon12eder

15
'const' 는 가독성을 향상시킵니다 . 이 문장은 obj가 변경되지 않을 수 있음을 분명히합니다!
찰스

14
가독성에 도움이되는 것은 각 쉼표 뒤에 공백을 추가하는 것입니다.
sam hocevar

답변:


182

가독성은 공백을 사용하는 법을 배우는 유효한 이유입니다.

void MyClass::myFunction(
        const MyObject& obj,
        const string& s1,
        const string& s2,
        const string& s3
) {
    return;
}

저쪽에있는 매개 변수는 함수 본문과 혼동되지 않습니다. 다른 줄에 배치하면 이름을 myFunction더 설명적인 이름으로 변경할 때 위치를 바꿀 필요가 없습니다 . 변경되지 않았을 때 매개 변수 위치를 변경하지 않는 것은 소스 제어 diff 도구 사용자가 좋아할만한 것입니다.

const뭔가를 의미합니다. 공간과 아이디어가 부족하여 버리지 마십시오. 가독성은 왕이지만 그 이름으로 물건을 깨는 것은 단지 포기입니다.


6
"myFunction의 이름을 변경할 때 위치를 변경할 필요가 없습니다"-이 경우 마치 개구부와 대략적으로 일치하는 것처럼 보이지만이 경우에는 위치를 바꿔야 (할 수도 있습니다. 클래스 + 함수 이름의 길이가 약 4 자 이상 변경되면 따라서 그렇게하지 않으려면 함수 이름의 길이에 의존하는 숫자가 아닌 고정 된 수준의 들여 쓰기를 추가하십시오. 나는 1 레벨을 추천하고,이 답변은 6을 사용하지만, 고정 된 숫자는 명시된 목표를 달성합니다 :-)
Steve Jessop

6
@CandiedOrange이 답변에 "form 6"을 사용하지 않았다는 것이 놀랍습니다 ... 분명히 추악합니다!
svidgen

6
승리를위한 양식 6 한 단계의 들여 쓰기를위한 하나의 탭 공간. 간단하고 효과적입니다. 문제 해결 :)
가벼움과 모니카

2
좋아, 6 번 양식입니다. 이것은 JeffGrigg가 c2에서 언급 한 변형입니다.
candied_orange

4
@ random832 자전거 타는 영토에 있다고 생각합니다. 이를 해결하는 올바른 방법은 다음과 같습니다. 코드베이스에서 예제를 검색하고, 상점 스타일 가이드를 참조하고, 상점의 개발자에게 문의하십시오. 한 분기에 갈 수있는 분쟁을 해결하십시오. 분기가 말하면 일관성!
candied_orange

52

실제로, 가독성 문제는 다른 방향으로 진행됩니다. 먼저 공백을 사용하여 런온 라인을 간단하게 해결할 수 있습니다 . 그러나 제거 const하면 줄이 짧아 질뿐 아니라 프로그램의 의미가 완전히 바뀝니다.

허브 셔터은을 참조 const로 참조 const는 AS 가장 중요const 하기 때문에 참조 const캔 바인드 임시로 그 수명을 연장. 비값에 대한 lvalue 참조 const는 별도의 변수가 필요합니다.

void foo_const(std::string const& );
void foo_nc(std::string& );

std::string some_getter();

foo_const(some_getter());      // OK
foo_const("Hello there"); // OK

foo_nc(some_getter()); // error
foo_nc("Nope");   // error

std::string x = some_getter(); // have to do this
foo_nc(x);                     // ok
std::string msg = "Really??";  // and this
foo_nc(msg);                   // ok

이것이 유용성을 의미하는 것은 함수를 호출 할 수 있도록 이러한 모든 임시 변수를 도입해야한다는 것입니다. 이러한 변수는 의미가 없으며 서명이 잘못 되었기 때문에 존재하기 때문에 가독성이 좋지 않습니다.


6
두 번째 문단은 나에게 다른 쪽을 const언급 하고 있는지, 그리고 가장 중요한 것이 무엇인지 알아 내려고하는 두통을줍니다.constconstconstconst
Mindwin

3
@ Mindwin 나는 두 번째 단락이 명확하고 모호하지 않으며, 당신이 무슨 말을하는지 전혀 모른다는 아이러니라고 생각합니다.
Barry

2
@Barry 그것은 분명하다. 그러나 그것이 의미하는 바를 알아 내기 위해 그 단락을 읽는 데 약간의 시간이 걸렸다. 문제의 일부는 "Herb Sutter가 const를 참조하는 const를 가장 중요한 const로 참조합니다."또는 "Herb Sutter가 const를 (const 참조)를 가장 많이 참조하는 것으로 해석 할 수 있다는 것입니다. 중요한 const ... "나는 후자가 유일한 유효한 단어 그룹이라고 생각하지만, 그것을 처리하는 데 약간의 시간이 걸립니다. 모호성을 제거하기 위해 따옴표를 사용하는 방법이 있습니까?
Cort Ammon-복원 모니카

1
하이픈 처리 된 일부 화합물이이를 ​​해결할 것이라고 생각합니다.
shawnt00

2
또는 명사 ( const&const
구절

21

간단한 대답은 "아니오"입니다.

긴 대답은 const키워드가 기능이 제공하는 계약의 일부라는 것입니다. 인수가 수정되지 않음을 알려줍니다. const보증 을 제거하는 순간 창 밖으로 나옵니다. 문서, 규칙 또는 지침을 사용하여 무언가의 일관성 (또는 기타 속성)을 합리적으로 유지할 수는 없습니다. 컴파일러가 불변성을 강요하지 않으면 누군가 작업을 더 쉽게 할 수 있다고 생각할 것입니다. "조금만"매개 변수. 치다:

// parameter "foo" is not modified
void fna(Foo& foo);

void fnb(const Foo& foo);

후자의 버전이 더 간결하다는 사실 외에도 강력한 계약을 제공하며 컴파일러가 의도를 유지하도록 도와줍니다. 전자는 fna(Foo&)함수가 전달한 매개 변수를 수정하는 것을 막지 않습니다 .

@CandiedOrange 답변에서와 같이 공백을 사용하여 코드를 레이아웃하고 가독성을 향상시킬 수 있습니다.


14

제거 중 const키워드를 제거합니다 가독성을 하기 때문에 const통신하는 정보 독자와 컴파일러.
가로 길이의 코드를 줄이는 것이 좋지만 (옆으로 스크롤하는 것을 좋아하는 사람은 없지만) const텍스트 이상의 것이 있습니다. 다시 쓸 수 있습니다.

typedef string str;
typedef MyObject MObj;
void MyClass::myFunction(const MObj& o,const str& s1,const str& s2,const str& s3)

계약을 변경하지는 않지만 라인 길이를 줄여야 할 필요성을 충족시킵니다. 정말 내가 덜 읽을 수 위의 조각을 고려할 것이라고 이미 CandiedOrange의 대답에 언급 한 바와 같이 많은 공백을 사용하여 선택할 것입니다.

const코드 자체의 기능입니다. MyClass::선언 의 섹션 을 제거하기 위해 함수를 비 멤버로 만들지 않으므로 제거하지 마십시오.const


4
귀하가 제공하는 스 니펫이 읽기 쉽지 않다는 데 동의합니다. 그것은 무엇을 찾아 갈 리더를 강제 MObj하고 str있으며, 확실히 눈썹을 제기한다. 예 : 왜 당신은 그냥 이름을하지 않았다 : 그것은 이름이 이미 제어 할 수 있습니다 유형에 특히 이상해 MyObjectMObj시작하는?
Jason C

3

가독성이 매개 변수에 const를 사용하지 않는 유효한 이유입니까?

아니요. 생략 const하면 기능이 변경 const되고 보호 기능이 떨어지며 잠재적으로 덜 효율적인 코드가 생성 될 수 있습니다.

매개 변수 개체를 수동으로 변경하지 않고 유지할 수 있습니까?

코드를 수동으로 형식화하는 데 시간을 소비하지 말고

void MyClass::myFunction(const MyObject& obj,const string& s1,const string& s2,const string& s3){
  //
}

자동 서식 도구를 사용하십시오 . 기능 요구 사항에 따라 기능을 작성하고 자동 형식화로 프리젠 테이션을 처리하십시오. 서식을 수동으로 조정하는 것은 자동 서식을 사용하고 저장된 시간을 사용하여 코드의 다른 측면을 개선하는 것만 큼 효율적이지 않습니다.

void MyClass::myFunction(const MyObject& obj, const string& s1, const string& s2, 
    const string& s3) {
  // 
}

-1

가능한 한 const를 표시하는 것이 좋습니다. 코드 유지 관리가 많이 향상되었습니다 (이 방법이 내 인수를 변경하는지 알 수있는 추측은 없습니다).

메서드에서 많은 인수를 볼 경우 훨씬 짧고 이해하기 쉬운 프로젝트 기반 jaron (매트릭스, 직원, 사각형, 계정) 생성을 고려해야합니다 (메소드에 대한 긴 인수 목록 제거).


동의했다. 나는 그것을 지적하는 것을 주저했다. 따라서 "극단적 사건".
blackpen

@cmaster 즉, 특정 상황에서는 특정 프로그래머와 함께 읽을 수있는 상태로 유지 수 있습니다. 예를 들어, 허리 깊이의 윈도우 API 호출에서, 예를 들어 같은 그 환경에 사용되는 리더, 물건과 함께 프로그램의 매우 구체적인 경우 typedef Point * LPPOINTtypedef const Point * LPCPOINT는 즉각적인 기대에 부합 때문에, 슈퍼 불쾌한하면서, 여전히, 암시 적 의미를 전달 문맥. 그러나 일반적인 경우에는 결코 그렇지 않습니다. 내가 생각할 수있는 이상한 예외 일뿐입니다.
Jason C

1
그렇습니다. "const unsigned long long int"라는 질문이 떠 올랐지 만 "const"또는 "reference"라는 이점을 얻을 수있는 좋은 후보는 아닙니다. typedef는 일반적인 이름 단축 문제를 해결합니다. 그러나 그 뒤에 "const"와 같은 언어 구성의 목적을 숨기는 것이 좋은 디자인은 아닙니다.
blackpen
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.