tags:

views:

628

answers:

4

I have a class which hold an array "float ** table". Now I want to have member function to return it, but don't want it to be modified outside of the class. So I did this:

class sometable 
{
  public:
   ...
   void updateTable(......);
   float **getTable() const {return table;}
  private:
    ...
    float **table;
}

This compiles OK when I call getTable with a constant object. Now I tried to make it safer by declaring getTable as "const float **getTable()". I got the following compilation error:

Error:
  Cannot return float**const from a function that should return const float**.

Why? How can I avoid table to be modified out side of the class?

+5  A: 

Declare your method like this:

float const* const* getTable() const {return table;}

or

const float* const* getTable() const {return table;}

if you prefer.

Martin Liversage
Yes, it worked! (I used the second format :-)Thanks a lot!
+1  A: 

You could declare your method as

const float * const * const getTable() const {return table;}

but even this (the outermost const - next to the function name) would not prevent the client to try to delete it. You could return reference instead, but the best would be to use an std::vector for table and return const ref to it - unless using a C style array is a must

CsTamas
"Developers have better things to do than intentionally break their APIs." :)
280Z28
Although you are correct about returning a reference to `std::vector`
280Z28
The last const is not necessary and does change what can be done with the returned value.
Martin Liversage
Sure - the last const is just syntactic sugar, it will be an rvalue. And with all the efforts, the client could still break it, because in C++ you have "total" control
CsTamas
+2  A: 

You can't assign a float** to a float const** because it would allows to modify a const object:

float const pi = 3.141592693;
float* ptr;
float const** p = &ptr; // example of assigning a float** to a float const**, you can't do that
*p = π  // in fact assigning &pi to ptr
*ptr = 3;  // PI Indiana Bill?

C and C++ rules differ about what is allowed.

  • C++ rule is that when you add a const before a star, you have to add a const before each following one.

  • C rule is that you can only add a const before the last star.

In both languages, you can remove a const only before the last star.

AProgrammer
Well, my rule was only for *adding*, not removing. In C++ as well as in C, you can remove const only before the last star (I've added this to the rule above as well). See 4.4/4 (my example is in fact the one from the standard)
AProgrammer
I have removed my previous comment since it was based on a misunderstanding of your answer.
Martin Liversage
+1  A: 

Though you can clearly type the syntax just like that, I find it much more readable to define some typedefs for multiple-dimension arrays.

struct M {
    typedef double* t_array;
    typedef const double t_carray;
    typedef t_array* t_matrix;
    typedef const t_carray* t_cmatrix;

    t_matrix values_;

    t_cmatrix values() const { return values_; }
    t_matrix  values()       { return values_; }
};
xtofl