Programing

C ++에서 기본 매개 변수 값을 어디에 두어야합니까?

lottogame 2020. 3. 20. 08:13
반응형

C ++에서 기본 매개 변수 값을 어디에 두어야합니까? [복제]


이 질문에는 이미 답변이 있습니다.

기본 매개 변수 값의 위치는 무엇입니까? 함수 정의, 선언 또는 두 위치 모두에서?


기본 매개 변수 값은 선언에 표시되어야합니다. 이것이 호출자가 보는 유일한 값이기 때문입니다.

편집 : 다른 사람들이 지적했듯이 정의에 대한 논쟁을 는 있지만 사실이 아닌 것처럼 모든 코드를 작성하는 것이 좋습니다.


어느 쪽이든 할 수 있지만 둘 다 할 수는 없습니다. 일반적으로 함수 선언에서 수행하면 모든 호출자가 해당 기본값을 사용할 수 있습니다. 그러나 함수 정의에서 대신 정의 를 볼 수있는 사용자 만 기본값을 사용할 수 있습니다.


C ++은 호출에 기본 매개 변수 논리를 배치합니다. 즉, 호출 한 위치에서 기본값 표현식을 계산할 수 없으면 기본값을 사용할 수 없습니다.

다른 컴파일 단위에는 일반적으로 선언 만 포함되므로 정의에 배치 된 기본값 표현식은 정의 컴파일 단위 자체에서만 (그리고 정의 후에, 즉 컴파일러가 기본값 표현식을 본 후) 사용할 수 있습니다.

가장 유용한 장소는 모든 사용자가 볼 수 있도록 선언 (.h)입니다.

일부 사람들은 구현에 기본값 표현식을 주석으로 추가하기를 좋아합니다.

void foo(int x = 42,
         int y = 21);

void foo(int x /* = 42 */,
         int y /* = 21 */)
{
   ...
}

그러나 이것은 복제를 의미하며 주석이 코드와 동기화되지 않을 가능성을 추가합니다 (주석 처리되지 않은 코드보다 나쁜 점은 잘못된 주석이있는 코드입니다!).


이 스레드는 "오래된"스레드이지만 여전히 다음을 추가하고 싶습니다.

다음 사례를 경험했습니다.

  • 클래스의 헤더 파일에는
int SetI2cSlaveAddress( UCHAR addr, bool force );
  • 그 클래스의 소스 파일에는
int CI2cHal::SetI2cSlaveAddress( UCHAR addr, bool force = false )
{
   ...
}

보다시피, 클래스 헤더 파일이 아닌 클래스 소스 파일에 "force"매개 변수의 기본값을 설정했습니다.

그런 다음 파생 된 클래스에서 해당 함수를 다음과 같이 사용했습니다 (유래 클래스는 기본 클래스를 공개 방식으로 상속했습니다).

SetI2cSlaveAddress( addr );

"force"매개 변수를 "false" 'for grant'로 가정한다고 가정합니다.

그러나 컴파일러 ( c ++ 11 모드에 있음 )가 불평하고 다음과 같은 컴파일러 오류가 발생했습니다.

/home/.../mystuff/domoproject/lib/i2cdevs/max6956io.cpp: In member function 'void CMax6956Io::Init(unsigned char, unsigned char, unsigned int)':
/home/.../mystuff/domoproject/lib/i2cdevs/max6956io.cpp:26:30: error: no matching function for call to 'CMax6956Io::SetI2cSlaveAddress(unsigned char&)'
/home/.../mystuff/domoproject/lib/i2cdevs/max6956io.cpp:26:30: note: candidate is:
In file included from /home/geertvc/mystuff/domoproject/lib/i2cdevs/../../include/i2cdevs/max6956io.h:35:0,
                 from /home/geertvc/mystuff/domoproject/lib/i2cdevs/max6956io.cpp:1:
/home/.../mystuff/domoproject/lib/i2cdevs/../../include/i2chal/i2chal.h:65:9: note: int CI2cHal::SetI2cSlaveAddress(unsigned char, bool)
/home/.../mystuff/domoproject/lib/i2cdevs/../../include/i2chal/i2chal.h:65:9: note:   candidate expects 2 arguments, 1 provided
make[2]: *** [lib/i2cdevs/CMakeFiles/i2cdevs.dir/max6956io.cpp.o] Error 1
make[1]: *** [lib/i2cdevs/CMakeFiles/i2cdevs.dir/all] Error 2
make: *** [all] Error 2

그러나 기본 클래스 헤더 파일에 기본 매개 변수를 추가했을 때 :

int SetI2cSlaveAddress( UCHAR addr, bool force = false );

기본 클래스의 소스 파일에서 제거했습니다.

int CI2cHal::SetI2cSlaveAddress( UCHAR addr, bool force )

그런 다음 컴파일러는 행복했고 모든 코드는 예상대로 작동했습니다 (함수에 하나 또는 두 개의 매개 변수를 줄 수 있습니다 SetI2cSlaveAddress())!

따라서 클래스 사용자뿐만 아니라 매개 변수의 기본값을 헤더 파일에 넣는 것이 중요하며 컴파일 및 기능면에서도 필연적 인 것 같습니다!


비 멤버, 공개 또는 보호 된 기능이 노출 된 경우 호출자는 해당 기능을 알고 있어야 하며 기본값 은 헤더에 있어야합니다 .

함수가 개인용이며 라인 외부인 경우, 클라이언트 재 컴파일을 트리거하지 않는 변경 사항을 허용하기 때문에 구현 파일에 기본값을 설정하는 것이 합리적입니다. 개발). 즉, 잠재적으로 혼란 스러울 수 있으며 헤더에 API를보다 직관적으로 제시하는 데 문서화 가치가 있으므로 타협을 선택하십시오. 강력한 이유가없는 경우 일관성이 가장 중요합니다.


선언은 일반적으로 가장 '유용'하지만 클래스 사용 방법에 따라 다릅니다.

둘 다 유효하지 않습니다.


좋은 질문입니다. 코더는 일반적으로 선언을 사용하여 기본값을 선언합니다. 컴파일러를 기반으로 한 방법 (또는 경고) 또는 다른 방법으로 개최되었습니다.

void testFunct(int nVal1, int nVal2=500);
void testFunct(int nVal1, int nVal2)
{
    using namespace std;
    cout << nVal1 << << nVal2 << endl;
}

내가 언급 한 사람을 찾지 못한 한 가지 더 포인트 :

가상 메소드가있는 경우 각 선언마다 고유 한 기본값을 가질 수 있습니다!

어떤 값을 사용할지를 호출하는 인터페이스에 따라 다릅니다.

이데온의

struct iface
{
    virtual void test(int a = 0) { std::cout << a; }
};

struct impl : public iface
{
    virtual void test(int a = 5) override { std::cout << a; }
};

int main()
{
    impl d;
    d.test();
    iface* a = &d;
    a->test();
}

인쇄 50

나는 당신이 이것을 이렇게 사용하지 않는 것이 좋습니다.


표준에 따라 둘 중 하나를 수행 할 수 있지만 코드에 기본 인수가 포함 된 정의 전에 기본 인수가없는 선언이 표시되면 컴파일 오류가 발생할 수 있습니다.

예를 들어, 기본 인수 목록없이 함수 선언을 포함하는 헤더를 포함하면 컴파일러는 기본 인수 값을 모르므로 프로토 타입이 일치하지 않으므로 해당 프로토 타입을 찾습니다.

기본 인수로 함수를 정의에 넣는 경우 해당 파일을 포함 시키지만 제안하지는 않습니다.


하나 더 포인트를 추가합니다. 기본 인수가있는 함수 선언 은 오른쪽에서 왼쪽으로 , 위에서 아래정렬 되어야합니다 .

예를 들어 아래 함수 선언에서 선언 순서를 변경하면 컴파일러에 누락 된 기본 매개 변수 오류가 발생합니다. 컴파일러가 동일한 범위 내에서 기본 인수로 함수 선언을 분리하도록 허용하는 이유는 RIGHT에서 LEFT (기본 인수) 및 TOP에서 BOTTOM (함수 선언 기본 인수의 순서) 순서 여야합니다.

//declaration
void function(char const *msg, bool three, bool two, bool one = false);
void function(char const *msg, bool three = true, bool two, bool one); // Error 
void function(char const *msg, bool three, bool two = true, bool one); // OK
//void function(char const *msg, bool three = true, bool two, bool one); // OK

int main() {
    function("Using only one Default Argument", false, true);
    function("Using Two Default Arguments", false);
    function("Using Three Default Arguments");
    return 0;
}

//definition
void function(char const *msg, bool three, bool two, bool one ) {
    std::cout<<msg<<" "<<three<<" "<<two<<" "<<one<<std::endl;
}

참고 URL : https://stackoverflow.com/questions/4989483/where-to-put-default-parameter-value-in-c

반응형