매개 변수 앞의 const vs 함수 이름 뒤의 const c ++


90

이런 것의 차이점은 무엇입니까

friend Circle copy(const Circle &);

그리고 이것과 같은

friend Circle copy(Circle&) const;

이 함수가 호출 된 개체를 변경하지 않을 것임을 컴파일러에 알리기 위해 함수가 사용 된 후 const를 알고 있습니다. 다른 함수는 어떻습니까?


6
당신이 매개 변수를 변경하지 않을 다른입니다
차드

답변:


199

첫 번째 형식은 함수 Circle의 매개 변수 인 참조에 바인딩 된 객체의 상태 가 해당 참조를 통해 copy()변경되지 않음 copy()을 의미합니다. 참조는에 대한 참조 const이므로 Circle자체적으로로 한정되지 않은 참조를 통해의 멤버 함수를 호출 할 수 없습니다 const.

반면에 두 번째 형식은 불법입니다. 멤버 함수const정규화 될 수 있습니다 (글로벌 friend함수 가 있다고 선언하는 동안 ).

const멤버 함수를 한정 할 때 한정은 암시 적 this인수를 참조합니다 . 즉, 해당 함수는 호출 된 객체 (암시 적 this포인터가 가리키는 객체)의 상태를 변경할 수 없습니다.mutable 없지만 이는 또 다른 이야기입니다.

코드로 말하려면 :

struct X
{
    void foo() const // <== The implicit "this" pointer is const-qualified!
    {
        _x = 42; // ERROR! The "this" pointer is implicitly const
        _y = 42; // OK (_y is mutable)
    }

    void bar(X& obj) const // <== The implicit "this" pointer is const-qualified!
    {
        obj._x = 42; // OK! obj is a reference to non-const
        _x = 42; // ERROR! The "this" pointer is implicitly const
    }

    void bar(X const& obj) // <== The implicit "this" pointer is NOT const-qualified!
    {
        obj._x = 42; // ERROR! obj is a reference to const
        obj._y = 42; // OK! obj is a reference to const, but _y is mutable
        _x = 42; // OK! The "this" pointer is implicitly non-const
    }

    int _x;
    mutable int _y;
};

12
Helluva 대답! 감사합니다!
SexyBeast 2015 년

1
그래서, 두 번째 경우에, 나는 경우 const객체 obj클래스를 X, 내가 전화 bar()처럼 obj.bar(obj)왜 일어날하도록되어 무엇? 호출자에서 선언되었으므로 obj._x = 42실패 하지 않아야 합니까? objconst
SexyBeast 2015 년

1
후자의 막대 함수 ( void bar(X const& obj) {...})를 이렇게 만드는 경우는 어떻습니까? void bar(const X& obj) {...}, const키워드를이 위치로 이동하면 변경되는 사항이 있습니까? 그렇다면이 예제도 추가해 주시겠습니까?
Gabriel Staples

1
@GabrielStaples 그들은 똑같습니다; const왼쪽에있는 것 또는 왼쪽에 아무것도없는 경우 오른쪽에있는 것에 적용됩니다. 귀하의 경우 두 버전 모두 const에 적용되는 것을 볼 수 X있습니다.
Andreas Flöjt

70

C ++ 클래스 메서드에는 this모든 명시 적 매개 변수 앞에 오는 암시 적 매개 변수가 있습니다. 따라서 다음과 같은 클래스 내에서 선언 된 함수 :

class C {
  void f(int x);

실제로 다음과 같은 모습을 상상할 수 있습니다.

  void f(C* this, int x);

이제 다음과 같이 선언하면 :

  void f(int x) const;

마치 당신이 이것을 쓴 것처럼 :

  void f(const C* this, int x);

즉, 후행 constthis매개 변수를 const로 만듭니다. 즉, 클래스 유형의 const 개체에서 메서드를 호출 할 수 있으며 메서드가 호출 된 개체를 수정할 수 없습니다 (적어도 일반 채널을 통하지 않음).


2
완벽하게 맞지만 실제로는 클래스 메서드가 아니라 친구 함수를 가리키는 질문에 대답하지 않습니다.
mah

5
네, friendOP의 실제 질문 (또는 모든 문제가 밝혀지면 실제 질문이 어떻게 될지)과는 무관하다고 생각하기 때문에 부분 을 무시하기로 결정했습니다 . 그러면 그렇게 해.
John Zwinck 2013-04-14

const 객체 또는 비 const 객체에 대해 const 메서드를 호출 할 수있는 반면 비 const 함수는 비 const 객체에 의해서만 호출 될 수 있기 때문에 "클래스 유형의 const 객체에 대해 메서드를 호출 할 수 있습니다"라고 말하는 것이 약간 오해의 소지가 있다고 생각합니다. 그렇지 않으면이 내가 제일 좋아하는 대답은
csguy

8
Circle copy(Circle&) const;

기능 const자체를 만듭니다 . 이것은 클래스 / 구조체의 멤버 함수에만 사용할 수 있습니다.

멤버 함수를 만드는 const것은

  • 그것은 할 수 없다상수가 아닌 멤버 함수를 호출
  • 그것을 할 수 있는 멤버 변수를 변경.
  • const객체에 의해 호출 될 수 있습니다 ( const객체는 const함수 만 호출 할 수 있음 ). 상수가 아닌 객체는 const함수를 호출 할 수도 있습니다.
  • 그것은 해야한다 클래스 '의 멤버 함수가 될 서클 '.

이제 다음을 고려하십시오.

Circle copy(const Circle &);

이것은 전달 된 매개 변수가 함수 내에서 변경 될 수 없음을 의미합니다. 클래스의 멤버 함수일 수도 있고 아닐 수도 있습니다.

참고 :const 동일한 함수의 상수가 아닌 버전을 가지도록 함수를 오버로드 할 수 있습니다.


8

다음과 관련된 모든 혼동을 제거합시다. const


const상수 에서 온 것은 무언가가 변경 불가능하지만 읽을 수 있음을 의미합니다.

  1. const키워드로 변수를 한정 하면 나중에 변경할 수 없습니다.
    예를 들어 const 변수는 선언 될 때 초기화되어야합니다.
    constint var =25;
    var =50; // gives error

  2. 우리가 우리의 포인터 변수를받을 자격이 있는지 우리는 할 수없는 포인터 자체를 변경하지만 포인터의 내용은 변경 . 예 //하지만const *

    int *const ptr = new int;
    ptr = new int; //gives error

    *ptr=5445; //allowed

  3. 우리가 우리의 포인터 변수를받을 자격이 있는지 전에 우리는 자체가 포인터를 변경할 수 있지만, 포인터의 내용은 변경할 수 없습니다 . 예 //하지만const *

    intconst* ptr = new int(85);
    //or
    constint * ptr = new int(85);
    ptr = new int; // allowed

    *ptr=5445; // gives error

  4. 포인터와 내용 모두 상수

    intconst*constptr = new int(85);
    //or
    constint *constptr = new int(85);
    ptr = new int; // not allowed
    *ptr=5445; // not allowed


  1. Circle copy(const Circle &);
    여기서 const Circle은 Circle의 값을 읽을 수만 있음을 의미하며, 함수 내에서 Circle의 값을 변경하려고하면 오류가 발생합니다.
  2. friend Circle copy(Circle&) const;
    이 유형의 함수는 멤버가 아닌 변수를위한 것이 아닙니다. 클래스 또는 구조에 사용됩니다. 여기서 전체 함수는 const 키워드로 한정되어 개체 멤버 변수를 변경할 수 없습니다 . 예 :
    class A{ public :
              int  var;
              void fun1()
                    { var = 50; // allowed
                    } 
              void fun2()const
                       { var=50; //not allowed
                       }
           }; 

4

하나는 매개 변수를, 다른 하나는 함수를 나타냅니다.

Circle copy(const Circle &);

이것은 전달 된 매개 변수가 함수 내에서 변경 될 수 없음을 의미합니다.

Circle copy(Circle&) const;

const자격을 갖춘 기능은 멤버 함수 및 개체 자체의 데이터 멤버를 변경할 수 없습니다 수단에 사용됩니다. 귀하가 게시 한 예는 말도 안됩니다.

오른쪽에서 왼쪽으로 읽기

첫 번째 함수를 Circle copy(Circle const&);같은 의미 로 다시 작성하면 오른쪽에서 왼쪽으로 읽는 것이 유용하다는 것이 분명해집니다. 객체에 copy대한 const참조를 가져와 참조로 Circle객체를 반환 하는 함수입니다 Circle.


0

friend Circle copy(const Circle &);// 함수의 상수 매개 변수를 나타냅니다. 매개 변수에 저장된 값을 변경할 수 없습니다.

예제에서 친구를 제거해야합니다. Circle copy (Circle &) const; // 상수 멤버 함수로 명명 된이 값을 변경할 수 없습니다.


0
friend Circle copy(const Circle &);

매개 변수의 값은 함수 호출 중에 변경되지 않습니다.

friend Circle copy(const Circle &)const ; 

이 함수는 클래스 멤버의 값을 변경하지 않는 접근 자입니다. 일반적으로 함수 유형에는 접근 자와 뮤 테이터가 있습니다. 접근 자 : 개체의 상태를 검사하지만 변경하지는 않습니다.

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