const перед параметром проти const після імені функції c ++


86

Яка різниця між чимось подібним

friend Circle copy(const Circle &);

і щось подібне

friend Circle copy(Circle&) const;

Я знаю const після того, як функція використовується для того, щоб повідомити компілятору, що ця функція не намагатиметься змінити об'єкт, до якого вона викликається, а як щодо іншого?


6
що ви не зміните параметр, це інше
Чад

Відповіді:


194

Перша форма означає, що 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;
};

11
Відповідь Гелува! Дякую!
SexyBeast

1
Отже, для другого випадку, якщо у мене є constоб’єкт objкласу X, і я називаю, bar()як obj.bar(obj), що має відбутися і чому? Не повинен obj._x = 42провалитися, оскільки objце оголошено constу абонента?
SexyBeast

1
А як щодо випадку, коли ви робите останню функцію панелі ( void bar(X const& obj) {...}) виглядати так? void bar(const X& obj) {...}, чи constщось змінює переміщення ключового слова до цього місця? Якщо так, чи можете ви також додати цей приклад?
Габріель Стейплз

1
@GabrielStaples Вони однакові; constзастосовується до того, що знаходиться зліва, або до того, що знаходиться праворуч, якщо зліва немає нічого. У вашому випадку ви побачите, що для обох версій constзастосовується X.
Андреас Флойт,

69

Методи класу С ++ мають неявний 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);

Тобто, відстеження constробить thisпараметр const, що означає, що ви можете викликати метод для об’єктів const типу класу, і що метод не може змінити об’єкт, для якого він був викликаний (принаймні, не через звичайні канали).


2
Цілком коректно, однак він не відповідає на запитання, яке насправді не стосується методу класу, а скоріше функцію друга.
mah

5
Так, я вирішив проігнорувати цю friendчастину, оскільки вважаю, що вона насправді не має значення для справжнього питання ОП (або яким справжнім питання стане, як тільки всі проблеми з’являться). Тож нехай так.
Джон Цвінк,

я думаю, що це трохи оманливе твердження "ви можете викликати метод на об'єктах const типу класу", оскільки ви можете викликати метод const на об'єктах const або об'єктах, що не є const, тоді як функції, які не є const, можуть викликатися лише об'єктами, що не є const. інакше це моя улюблена відповідь
csguy

8
Circle copy(Circle&) const;

робить саму функцію const. Це можна використовувати лише для функцій-членів класу / структури.

Створення функції-члена constозначає, що

  • він не може викликати будь-які функції, що не є const
  • він не може змінити жодних змінних-членів.
  • його може викликати constоб'єкт ( constоб'єкти можуть викликати лише constфункції). Неконстантні об'єкти також можуть викликати constфункцію.
  • Це повинна бути функція-член класу ' Circle '.

Тепер розглянемо наступний:

Circle copy(const Circle &);

в той час як це означає, що переданий параметр не може бути змінений у межах функції. Це може бути або не бути функцією-членом класу.

ПРИМІТКА: Можна перевантажити функцію таким чином, щоб мати constта неконстантну версію тієї самої функції.


7

ДАЙТЕ ОЧИСТИМО ВСЮ ПУТИНКУ, ПОВ'ЯЗАНУ З 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 &) const; // неможливо змінити це значення понітера, назване як функція постійного члена


-1
friend Circle copy(const Circle &);

Значення параметра не буде змінено під час викликів функції.

friend Circle copy(const Circle &)const ; 

Функція є засобом доступу, який не змінює значення членів класу. Як правило, існують типи функцій: аксесуари та мутатори. Аксесуар: перевіряє, але не змінює стан свого об'єкта.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.