Как вернуть const Float ** из функции С++

У меня есть класс, который содержит массив "float ** table". Теперь я хочу, чтобы функция-член возвращала его, но не хочу, чтобы он был изменен вне класса. Поэтому я сделал это:

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

Это компилируется ОК, когда я вызываю getTable с постоянным объектом. Теперь я попытался сделать его более безопасным, объявив getTable как "const float **getTable()". я получил следующая ошибка компиляции:

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

Почему? Как я могу избежать изменения таблицы вне класса?

Ответ 1

Объявите свой метод следующим образом:

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

или

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

если вы предпочитаете.

Ответ 2

Вы не можете назначить float** для float const**, потому что это позволит изменить объект const:

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 и С++ отличаются тем, что разрешено.

  • Правило С++ заключается в том, что когда вы добавляете const перед звездой, вам нужно добавить константу перед каждым следующим.

  • Правило C состоит в том, что вы можете добавлять константу только до последней звезды.

В обоих языках вы можете удалить константу только до последней звезды.

Ответ 3

Вы можете объявить свой метод как

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

но даже это (внешняя константа - рядом с именем функции) не помешает клиенту попытаться удалить его. Вместо этого вы могли бы возвратить ссылку, но лучше всего было бы использовать std::vector для таблицы и вернуть const ref для нее - если только использование массива стилей C не обязано

Ответ 4

Хотя вы можете четко ввести синтаксис именно так, я считаю его более читаемым, чтобы определить некоторые typedef для многомерных массивов.

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