Почему в этом случае я не могу передать this методу внутреннего класса?

avatar
JensB
8 августа 2021 в 19:23
70
1
0

У меня есть класс, содержащий внутренний класс, который выглядит примерно так:

class Foo
{
    class Bar
    {
    public:
        void update(const Foo& f)
        {
            //Updates using public getters of Foo
        }
    };
public:
    void doStuff() const
    {
        b_.update(*this);
    }
private:
    Bar b_;
};

Строка b_.update(*this) в настоящее время выдает ошибку cannot convert 'this' pointer from 'const Foo::Bar' to 'Foo::Bar &'

Почему? Параметр метода update имеет тип const Foo&, что означает, что он не может изменить объект Foo, если захочет. Разве это не должно удовлетворять методу const doStuff?

Я уже час пытаюсь поискать в гугле кого-то, у кого такая же проблема, но не могу правильно сформулировать вопрос, чтобы найти похожий вопрос.

Возможно ли то, что я пытаюсь сделать, или мне нужно изменить свой дизайн?

Источник
IlCapitano
8 августа 2021 в 19:25
0

У Clang большое сообщение об ошибке.

Eljay
8 августа 2021 в 19:27
0

Похоже, метод doStuff не должен быть помечен как const.

Pete Becker
8 августа 2021 в 19:44
0

Обратите внимание, что в С++ нет понятия "внутренний класс". В Java есть штука с таким названием, а в C++ нет ничего, что делало бы то же самое. Обычно Bar упоминается как вложенный класс.

Ответы (1)

avatar
Alan Birtles
8 августа 2021 в 19:26
5

doStuff равно const, поэтому b_ также является const в этом контексте, поэтому вызов неконстантной функции update не допускается.

Если doStuff необходимо изменить b_, его не следует помечать как const, можно пометить b_ как mutable, но это редко бывает правильным.<9913490>1049484

JensB
8 августа 2021 в 19:51
0

Никогда раньше не слышал о ключевом слове mutable. Объявление b_ как mutable действительно решило проблему, но я понимаю, что это не идеально. Метод с пометкой const никогда не должен изменять члены. Считаете ли вы такое использование приемлемым, если функциональность члена b_ используется только внутри Foo для помощи в некоторых вычислениях? Или мне следует изменить свой дизайн, чтобы Bar не был вложенным классом, а был объявлен вне Foo?

Alan Birtles
8 августа 2021 в 19:56
2

Единственное действительно допустимое использование mutable - это для таких вещей, как кэши, где вызов метода доступа (который, как вы ожидаете, будет const) должен иметь возможность обновлять кэшированное значение, поэтому это значение должно быть mutable . Если вызов метода не вносит внешне видимых изменений в класс, то, вероятно, разумно пометить его const и при необходимости иметь члены mutable. Bar, будучи вложенным классом, не влияет на это поведение.