Подтвердить что ты не робот

Может ли функция-член const возвращать неконстантный указатель на элемент данных?

Первый код:

class A
{
    public:
        ...
        int *foo() const
        {
            return _px;
        }
    private:
        int *_px;
}

Функция-член foo возвращает указатель не const для private member _px, который, я думаю, открывает дверь для изменения члена _px, правильно?

Является foo a const функцией-членом? Должен ли я добавить const перед типом возврата?

UPDATE

Что должна гарантировать функция const-member-функция, она не может изменить какой-либо элемент данных, правильно?

В моем случае функция foo не открывает дверь для изменения class A данных-члена _px, но открывает дверь для изменения того, что указывает _px. Так что мой вопрос заключается в том, что это нарушает то, что функция const должна гарантировать?

4b9b3361

Ответ 1

Функция

A const может возвращать только указатель const или ссылку на элемент.

Однако ваш пример не возвращает указатель на элемент; он возвращает копию члена, который является указателем. Это допускается в функции члена const (даже если указатель указывает на другой член).

Это не будет разрешено (обратите внимание, что теперь он возвращает ссылку):

int *& foo() const {return _px;}

но это будет (возврат ссылки const):

int * const & foo() const {return _px;}

Ответ 2

int *_px становится int *const _px внутри функции-члена const, это означает, что указатель не может быть повторно удален, но указанные данные все еще могут быть изменены. Далее ваша функция возвращает копию указателя, поэтому это не имеет значения.

Ответ 3

Он не открывает дверь для изменения _px, а скорее указывает _px. Вам решать, хотите ли вы это разрешить или нет.

Например, iterator::operator-> вернет указатель не const, а const_iterator::operator-> вернет указатель const. Оба метода могут быть самими константами.

Ответ 4

Да, для вашего случая это возможно. Однако обычно рекомендуется не делать этого, поскольку он позволяет изменять постоянные объекты:

void f(const A& a) 
{
  *(a.foo()) = 42; // damn!
}