You are not logged in.

aquavitae

Beginner

  • "aquavitae" is male
  • "aquavitae" started this thread

Posts: 12

Location: South Africa

Occupation: Engineer

  • Send private message

1

Wednesday, April 11th 2007, 8:39am

How do I deal with const

I'm having a general problem with const in classes. Here's a trivial example:

Source code

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
class MyClass {
   private:
      QString* data1;
      QString* data2;

      // Return a number depending on the value of param
      QString* privateData(const int param);

   public:
      // Return a string reflecting the internal data
      const QString readData(const int param) const;

      // Append to the internal data
      void appendData(const int param, QString* value);

      // Add ctors/dtors, etc
};

QString* MyClass::privateData(const int param) {
   if (param == 1)
      return data1;
   else
      return data2;
}

const QString* MyClass::readData(const int param) const {
   const QString* data = privateData(param);
   return data;
}

void MyClass::appendData(const int param, QString* value) {
   QString* data = privateData(param);
   data->append(&value);
}


This example doesn't do much, but it illustrates my problem: the fundtion appendData uses the function privateData to find a QString, then writes to it. For this reason, privateData cannot be const. However, the compiler (mingw) throws an error in the function readData as it is const but is calling privateData, which is not const.

I think I could probably use const_cast to deal with this, but I'd rather find a better way, if there is one. I've always thought casts to be a bit of a hack!

Does anyone know how to do this?

helcaraxe

Beginner

  • "helcaraxe" is male

Posts: 31

Location: Bavaria, Germany

Occupation: software engineer

  • Send private message

2

Wednesday, April 11th 2007, 11:47am

Hi,

The compiler is right about that :)
You declare readData as const, which tells the compiler that the code within it doesn't change the object. But you call a method which could change it because it isn't declared "const" itself. It does not change the object in your case, but the compiler just sees "Ah, the user calls a non const method from within a const method, I don't allow this no matter if the method does or doesn't change the object."

You could solve this by declaring privateData const -- just as readData.

So long,
Jan

aquavitae

Beginner

  • "aquavitae" is male
  • "aquavitae" started this thread

Posts: 12

Location: South Africa

Occupation: Engineer

  • Send private message

3

Wednesday, April 11th 2007, 12:04pm

Hi Jan

Thanks for the reply.

I get why the compiler complains, but if I declare privateData const, I can't use it in appendData. Is there a way I can assure the compiler that I'm not going to change the data?

I've written another function constPrivateData which is basically a const_cast<const QString*>(privateData()), but its very messy.

agallers11

Beginner

Posts: 55

Location: MD, US

Occupation: Programmer

  • Send private message

4

Wednesday, April 11th 2007, 3:00pm

You may want to look into mutable variables - the mutable keyword lets const member functions modify mutable member variables.

helcaraxe

Beginner

  • "helcaraxe" is male

Posts: 31

Location: Bavaria, Germany

Occupation: software engineer

  • Send private message

5

Wednesday, April 11th 2007, 5:00pm

Hej,

Sorry for pointing out something that might have been obvious, maybe I misunderstood your original problem ;)

I would not use "mutable" to annul the const qualifier. In fact I would implement two methods with different signature ("const X* bla(blubb) const" and "X* bla(blubb)" to circumvent this.

So long,
Jan

agallers11

Beginner

Posts: 55

Location: MD, US

Occupation: Programmer

  • Send private message

6

Wednesday, April 11th 2007, 6:04pm

Yea it didn't read the example before talking about mutable - Jan's idea looks like a good shortcut.

aquavitae

Beginner

  • "aquavitae" is male
  • "aquavitae" started this thread

Posts: 12

Location: South Africa

Occupation: Engineer

  • Send private message

7

Thursday, April 12th 2007, 9:16am

Thanks for the help!

The actual function I'm working on is quite a long one, and I don't want to duplicate it so I suppose the overloaded function will still have to const_cast the original one.

I've never used mutable before so I have no idea how it would work in this situation, but I think I'll have a look at in anyway - sounds interesting!

helcaraxe

Beginner

  • "helcaraxe" is male

Posts: 31

Location: Bavaria, Germany

Occupation: software engineer

  • Send private message

8

Thursday, April 12th 2007, 10:41am

Mutable

Thanks for that approval :)

I always considered mutable one hack method to repair design errors which are too deep inside to fix them afterwards. I don't like these methods, because the code becomes more complex and unreadable -- not talking about maintenance :D

If i really have to make such things, I try to leave a comment for my successors. Of course, in home-only or university one man project hacks these things could impress a few professors (but only a few, AFAIK, and mine wasn't among them).


So long,
Jan