const trước tham số so với const sau tên hàm c ++


87

Sự khác biệt giữa một cái gì đó như thế này là gì

friend Circle copy(const Circle &);

và một cái gì đó như thế này

friend Circle copy(Circle&) const;

Tôi biết const sau khi hàm được sử dụng để nói với trình biên dịch rằng hàm này sẽ không cố gắng thay đổi đối tượng mà nó được gọi, còn đối tượng kia thì sao?


6
rằng bạn sẽ không thay đổi các tham số là khác
Chad

Câu trả lời:


194

Dạng đầu tiên có nghĩa là Circleđối tượng (trạng thái của) liên kết với tham chiếu là tham số của copy()hàm sẽ không bị thay đổi copy()thông qua tham chiếu đó. Tham chiếu là một tham chiếu đến const, vì vậy sẽ không thể gọi các hàm thành viên của Circlethông qua tham chiếu đó mà bản thân nó không đủ điều kiện const.

Mặt khác, dạng thứ hai là bất hợp pháp: chỉ các hàm thành viên mới có thể constđủ tiêu chuẩn (trong khi những gì bạn đang khai báo là một friendhàm toàn cục ).

Khi constđủ điều kiện một chức năng thành viên, điều kiện tham chiếu đến thisđối số ngầm định . Nói cách khác, hàm đó sẽ không được phép thay đổi trạng thái của đối tượng mà nó được gọi (đối tượng được trỏ tới bởi thiscon trỏ ngầm định ) - ngoại trừ các mutableđối tượng, nhưng đó là một câu chuyện khác.

Để nói điều đó bằng mã:

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;
};

11
Helluva answer! Thank you!
SexyBeast

1
So, for the second case, if I have a const object obj of class X, and I call bar() like obj.bar(obj), what is supposed to happen and why? Shouldn't obj._x = 42 fail, since obj is declared const in the caller?
SexyBeast

1
What about the case where you make the latter bar function (void bar(X const& obj) {...}) look like this? void bar(const X& obj) {...}, does moving the const keyword to this location change anything? If so, can you add this example too please?
Gabriel Staples

1
@GabrielStaples They're the same; const applies to what is on its left, or to what is on its right in case there is nothing to the left. In your case you'll see that for both versions const is applied to X.
Andreas Flöjt

69

C++ class methods have an implicit this parameter which comes before all the explicit ones. So a function declared within a class like this:

class C {
  void f(int x);

You can imagine really looks like this:

  void f(C* this, int x);

Now, if you declare it this way:

  void f(int x) const;

It's as if you wrote this:

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

That is, the trailing const makes the this parameter const, meaning that you can invoke the method on const objects of the class type, and that the method cannot modify the object on which it was invoked (at least, not via the normal channels).


2
Perfectly correct however it doesn't answer the question, which isn't actually referring to a class method but rather a friend function.
mah

5
Yeah, I chose to ignore the friend part because I think it's actually irrelevant to the OP's real question (or what the real question will become once all the issues come to light). So be it.
John Zwinck

i think its slightly misleading to say "you can invoke the method on const objects of the class type" because you can invoke const method on const objects or non const objects, while non-const functions can only be called by non-const objects. otherwise this is my favorite answer
csguy

8
Circle copy(Circle&) const;

makes the function const itself. This can only be used for member functions of a class/struct.

Making a member function const means that

  • it cannot call any non-const member functions
  • it cannot change any member variables.
  • it can be called by a const object(const objects can only call const functions). Non-const objects can also call a const function.
  • It must be member function of the class 'Circle'.

Now consider the next one:

Circle copy(const Circle &);

while this one means that the parameter passed cannot be changed within the function. It may or may not be a member function of the class.

NOTE: It is possible to overload a function in such a way to have a const and non-const version of the same function.


7

LET'S CLEAR ALL CONFUSION RELATED TO const


const came from constant mean something is not changeable but readable.

  1. if we qualify our variable with const keyword ,we can't change it later.
    e.g.
    constint var =25; const variable must be initialized when it's declared.
    var =50; // gives error

  2. if we qualify our pointer variable with const after * then we can't change pointer itself but content of pointer is changeable.
    e.g.
    int *const ptr = new int;
    ptr = new int; //gives error
    // but
    *ptr=5445; //allowed

  3. if we qualify our pointer variable with const before * then we can change pointer itself but content of pointer is not changeable.
    e.g.
    intconst* ptr = new int(85);
    //or
    constint * ptr = new int(85);
    ptr = new int; // allowed
    // but
    *ptr=5445; // gives error

  4. pointer and content both constant
    e.g.
    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 &);
    here const Circle means value of Circle is only readable ,if we try to change value of Circle inside function then it gives error.
  2. friend Circle copy(Circle&) const;
    This type of function is not for non member variable .it is used for class or structure. Here whole function is qualified with const keyword means we can't change object member variable . e.g
    class A{ public :
              int  var;
              void fun1()
                    { var = 50; // allowed
                    } 
              void fun2()const
                       { var=50; //not allowed
                       }
           }; 

4

One refers to the parameter the other to the function.

Circle copy(const Circle &);

This means that the parameter passed in cannot be changed within the function

Circle copy(Circle&) const;

The const qualified function is used for member functions and means you cannot change the data members of the object itself. The example you posted was nonsensical.

Read right-to-left

If we rewrite the first function as Circle copy(Circle const&);, which means the same thing, it becomes clear that reading right to left becomes useful. copy is a function that takes a const reference to a Circle object and returns a Circle object by reference.


0

friend Circle copy(const Circle &);//refers to constant parameter of the function. cant' change the value stored by parameter.

Need to remove friend in your example Circle copy(Circle&) const; //can't change this poniter value named as Constant member function


-1
friend Circle copy(const Circle &);

The value of parameter will not be changed during the function calls.

friend Circle copy(const Circle &)const ; 

The function is an accessor that does not change any value of class members. Generally, there are to types of functions: accessors and mutators. Accessor: examines but does not change the state of its object.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.