NoSenseEtAl
NoSenseEtAl

Reputation: 30006

Is there a way in c++ to make sure that class member function isnt changing any of the class data members?

Lets say that I have a

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

Is there a way to make compiler check that contains isnt changing words vector. Ofc this is just an example with one class data member, I would like it to work with any number of data members. P.S. I know i have no public: and private:, I left it out intentionally to make code shorter and problem clearer.

Upvotes: 3

Views: 253

Answers (5)

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272467

If you want the compiler to enforce this, then declare the member function const:

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

A const function is not allowed to modify its member variables, and can only call other const member functions (either its own, or those of its member variables).

The exception to this rule is if the member variable is declared as mutable. [But mutable should not be used as a general-purpose const workaround; it's only really meant for when situations where the "observable" state of an object should be const, but internal implementation (such as reference-counting or lazy evaluation) still needs to change.]

Note also that const does not propagate through e.g. pointers.

So in summary:

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

Upvotes: 16

Luchian Grigore
Luchian Grigore

Reputation: 258568

declare your function as const:

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

If you try to change any members inside the body, the compiler will give an error. Also note that inside a method declared const, you can't call other methods that are not declared const.

Upvotes: 2

codaddict
codaddict

Reputation: 454960

Make the member function const:

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

Upvotes: 1

Xeo
Xeo

Reputation: 131789

Mark them as const:

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

Another positive thing: You can only call other const member functions! :) Yet another good thing: You're allowed to call those functions on const objects of your class, example:

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

Upvotes: 6

Diego Sevilla
Diego Sevilla

Reputation: 29011

Usually declaring the method as "const" achieves this:

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

The compiler will tell you if you use any method on the class members that is not also const. Note also that you could pass the string by reference to avoid copying (making the word parameter std::string const&).

Upvotes: 2

Related Questions