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

Код идет первым:

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

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

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

ОБНОВЛЕНИЕ

Функция const-member должна гарантировать, что она не может изменять какие-либо данные-член, верно?

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

Ответы [ 5 ]

32 голосов
/ 09 января 2012

A const функция-член может возвращать только указатель const или ссылку на член.

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

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

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

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

int * const & foo() const {return _px;}
5 голосов
/ 09 января 2012

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

4 голосов
/ 09 января 2012

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

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

2 голосов
/ 09 января 2012

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

void f(const A& a) 
{
  *(a.foo()) = 42; // damn!
}
0 голосов
/ 03 мая 2018

Да, например, смотрите указатели std :: streambuf:

protected:
   char* pbase() const;
   char* pptr() const;
   char* epptr() const;

http://en.cppreference.com/w/cpp/io/basic_streambuf/pptr

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...