Продай меня по правильности - PullRequest
115 голосов
/ 26 сентября 2008

Так почему же всегда рекомендуется использовать const как можно чаще? Мне кажется, что использование const может быть более болезненным, чем помощь в C ++. Но опять же, я подхожу к этому с точки зрения питона: если вы не хотите, чтобы что-то изменилось, не меняйте это. Итак, с учетом сказанного, вот несколько вопросов:

  1. Кажется, что каждый раз, когда я отмечаю что-то как const, я получаю сообщение об ошибке, и мне приходится где-то менять другую функцию, чтобы она тоже была const. Тогда это заставляет меня изменить другую функцию где-нибудь еще. Это что-то, что становится легче с опытом?

  2. Достаточно ли преимуществ использования const , чтобы компенсировать проблему? Если вы не собираетесь менять объект, почему бы просто не написать код, который его не меняет?

Я должен отметить, что в данный момент я больше всего сосредоточен на преимуществах использования const в целях корректности и удобства обслуживания, хотя также неплохо иметь представление о влиянии на производительность.

Ответы [ 16 ]

10 голосов
/ 26 сентября 2008

const помогает вам изолировать код, который «меняет вещи» за вашей спиной. Итак, в классе вы бы пометили все методы, которые не изменяют состояние объекта, как const. Это означает, что const экземпляры этого класса больше не смогут вызывать любые не-const методы. Таким образом, вы не сможете случайно вызвать функцию, которая может изменить ваш объект.

Кроме того, const является частью механизма перегрузки, поэтому вы можете использовать два метода с одинаковыми сигнатурами, но один с const и один без. Один с const вызывается для const ссылок, а другой - для не const ссылок.

Пример:

#include <iostream>

class HelloWorld {
    bool hw_called;

public:
    HelloWorld() : hw_called(false) {}

    void hw() const {
        std::cout << "Hello, world! (const)\n";
        // hw_called = true;  <-- not allowed
    }

    void hw() {
        std::cout << "Hello, world! (non-const)\n";
        hw_called = true;
    }
};

int
main()
{
    HelloWorld hw;
    HelloWorld* phw1(&hw);
    HelloWorld const* phw2(&hw);

    hw.hw();    // calls non-const version
    phw1->hw(); // calls non-const version
    phw2->hw(); // calls const version
    return 0;
}
5 голосов
/ 26 сентября 2008

Скажем, у вас есть переменная в Python. Вы знаете, что вы не должны изменить его. Что делать, если вы случайно делаете?

C ++ дает вам способ защитить себя от случайных действий, которые вы не должны были делать изначально. Технически вы можете обойти это в любом случае, но вы должны приложить дополнительные усилия, чтобы застрелиться.

4 голосов
/ 26 сентября 2008

Здесь есть хорошая статья о const в c ++. Это довольно прямолинейное мнение, но надеюсь, что это поможет некоторым.

3 голосов
/ 26 сентября 2008

Когда вы используете ключевое слово "const", вы указываете другой интерфейс для ваших классов. Существует интерфейс, который включает в себя все методы, и интерфейс, который включает только методы const. Очевидно, это позволяет вам ограничить доступ к некоторым вещам, которые вы не хотите изменять.

Да, со временем становится легче.

1 голос
/ 26 сентября 2008

Вы можете также дать подсказки компилятору с помощью const .... согласно следующему коду

#include <string>

void f(const std::string& s)
{

}
void x( std::string& x)
{
}
void main()
{
    f("blah");
    x("blah");   // won't compile...
}
1 голос
/ 26 сентября 2008

Мне нравится постоянная корректность ... в теории. Каждый раз, когда я пытался применять его строго на практике, он со временем ломался, и const_cast начинает ползти, делая код ужасным.

Возможно, я использую только шаблоны дизайна, но const всегда оказывается слишком широкой кистью.

Например, представьте себе простой механизм базы данных ... у него есть объекты схемы, таблицы, поля и т. Д. У пользователя может быть указатель "const Table", означающий, что ему не разрешено изменять саму схему таблицы ... но как насчет манипулирования данными, связанными с таблицей? Если метод Insert () помечен как const, то внутренне он должен отбросить константу, чтобы фактически манипулировать базой данных. Если он не помечен как const, он не защищает от вызова метода AddField.

Возможно, ответ состоит в том, чтобы разделить класс на основе требований к константности, но это имеет тенденцию усложнять конструкцию больше, чем я хотел бы для выгоды, которую он приносит.

...