Есть ли способ в C ++, чтобы убедиться, что функция-член класса не изменяет ни один из членов данных класса? - PullRequest
3 голосов
/ 02 июня 2011

Допустим, у меня есть

class Dictionary
{
vector<string> words;  
void addWord(string word)//adds to words
{
/...
}
bool contains(string word)//only reads from words
{
//...
}
}

Есть ли способ сделать проверку компилятором, которая не изменяет вектор слов?Ofc это просто пример с одним членом класса данных, я хотел бы, чтобы он работал с любым количеством членов данных.PS Я знаю, что у меня нет public: и private:, я намеренно оставил это, чтобы сделать код короче, а проблему - яснее.

Ответы [ 5 ]

16 голосов
/ 02 июня 2011

Если вы хотите, чтобы компилятор это применил, объявите функцию-член const:

bool contains(string word) const
{
    ...
}

Функция const не может изменять свои переменные-члены и может вызывать только другие const функции-члены (либо свои, либо функции своих переменных-членов).

Исключением из этого правила является то, что переменная-член объявлена ​​как mutable. [Но mutable не следует использовать как обходной путь const общего назначения;Он действительно предназначен только для ситуаций, когда «наблюдаемое» состояние объекта должно быть const, но внутренняя реализация (например, подсчет ссылок или отложенная оценка) все еще нуждается в изменении.]

Также обратите внимание, что const не распространяется, например, через указатели.

Итак, в итоге:

class Thingy
{
public:
    void apple() const;
    void banana();
};

class Blah
{
private:
    Thingy t;
    int *p;
    mutable int a;

public:
    Blah() { p = new int; *p = 5; }
    ~Blah() { delete p; }

    void bar() const {}
    void baz() {}

    void foo() const
    {
        p = new int;  // INVALID: p is const in this context
        *p = 10;      // VALID: *p isn't const

        baz();        // INVALID: baz() is not declared const
        bar();        // VALID: bar() is declared const

        t.banana();   // INVALID: Thingy::banana() is not declared const
        t.apple();    // VALID: Thingy::apple() is declared const

        a = 42;       // VALID: a is declared mutable
    }
};
6 голосов
/ 02 июня 2011

Отметьте их как const:

bool contains(string word) const
//                        ^^^^^^

Еще один положительный момент: вы можете вызывать только другие const функции-члены!:) Еще одна хорошая вещь: вы можете вызывать эти функции для const объектов вашего класса, например:

void foo(const Dictionary& dict){
  // 'dict' is constant, can't be changed, can only call 'const' member functions
  if(dict.contains("hi")){
    // ...
  }
  // this will make the compiler error out:
  dict.addWord("oops");
}
2 голосов
/ 02 июня 2011

объявите вашу функцию как const:

void addWord(string word) const { /... }

Если вы попытаетесь изменить какие-либо элементы внутри тела, компилятор выдаст ошибку.Также обратите внимание, что внутри метода, объявленного как const, нельзя вызывать другие методы, которые не объявлены как const.

2 голосов
/ 02 июня 2011

Обычно объявление метода как "const" достигает этого:

bool contains(string word) const
// ...

Компилятор сообщит вам, если вы используете какой-либо метод для членов класса, который также не является const. Также обратите внимание, что вы можете передать строку по ссылке, чтобы избежать копирования (сделав параметр word std::string const&).

1 голос
/ 02 июня 2011

Сделать функцию-член const:

bool contains(string word) const
{
//...
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...