C++, const методы

147
19 февраля 2019, 03:50

Рассмотрим пример:

class A
{
    public:
    float *GetValues() const
    {
        return values;
    }
    private:
    float values[10];
};

Законно ли в этом случае считать метод константным? Ведь сам он не меняет состояние класса, но предоставляет указатель на массив, и кто-то может изменить содержимое массива через этот указатель.

Answer 1

Нет, незаконно.

Мой GCC выдает error: invalid conversion from 'const float*' to 'float*'.

Внутри константного метода все поля (кроме mutable) считаются константными, так что values имеет тип const float [10]. Без const_cast он в float * не преобразуется.

Но если бы у вас в классе хранился не массив, а указатель - float *, то в константном методе он имел бы тип float *const (константный указатель на изменяемые float), а не const float * (изменяемый указатель на константные float). Такой указатель преобразовывался бы float * без проблем.

Answer 2

Чтобы метод был законно константным, нужно чуть изменить код - возвращайте из вашего метода указатель на константу (const float*), а не просто указатель (float*):

class A
{
    public:
    const float *GetValues() const
    {
        return values;
    }
    private:
    float values[10];
};
Answer 3

Начнем с того, что компилятор не даст вам так просто неявно преобразовать const float[10] в float* - вам придется выполнять приведение... Но при этом вы получите сообщение о том, что нельзя преобразовать константный массив в неконстантный указатель.

Так что да - такой метод не может быть константным. И поведение компилятора, который этот код компилировать не станет, это подтверждает :)

P.S. Конечно, компилятор можно уговорить кодом наподобие

return const_cast<float*>(values);

Но тогда уже вы отвечаете за то, что возвращаемым указателем никто не воспользуется неподобающим образом...

READ ALSO
JavaFx Проблема с временным открытием окна

JavaFx Проблема с временным открытием окна

Код немного кривой, но проблема заключается в создании окна в methodNormal при выполнении show() окно появляетьтся и его блокирует Threadsleep(5000) а мне...

173
BigInteger, как увеличить вводимую строку?

BigInteger, как увеличить вводимую строку?

Имеется число с = 2 в степени 77232917И хочу записать это число в BigInteger a = new BigInteger("с"); Но длина строки ограничена, можно как то увеличить её?

146