Функция непостоянного члена вызывается внутри функции постоянного члена

#include <iostream>

class Hello {
public:
void Test() {
std::cout << "Testing" << std::endl;
}
};

class Hi {
public:
Hi()
:hello(new Hello())
{}

~Hi()
{
delete hello;
}

void Testing() const {
hello->Test();
}

private:
Hello  * hello;
};

int main(int argc, char ** argv) {
Hi hi; ;
hi.Testing();
return 0;
}

Как я знаю, непостоянная функция-член не может быть вызвана внутри постоянной функции-члена, но как приведенный выше код был успешно скомпилирован и дает ожидаемый результат.

1

Решение

внутри Hi::Testing, hi объект «является постоянным». Что означает указатель hello не может быть изменено внутри этого метода. (Это как будто hello был определен как Hello * const hello; на время этого метода.)

Но это не значит, что hello превращается в указатель на const (который будет выглядеть Hello const * const hello;). Объект, на который указывает hello не const, так что вы можете вызывать его неконстантные методы без ограничений.

2

Другие решения

Вы можете свести проблему к следующей ситуации:

Foo x;

Foo       *       p1 = &x;
Foo       * const p2 = &x;

p1->non_const_method();     // OK
p2->non_const_method();     // OK

Foo const *       q1 = &x;
Foo const * const q2 = &x;

q1->non_const_method();     // error
q2->non_const_method();     // error

Будь или не твой Hi-объект постоянно влияет только на верхний уровень const модификатор в этой аналогии (т.е. Hi::hello является Hello * или же Hello * const). Тем не менее первый Модификатор const является неотъемлемой частью самого типа указателя (и не зависит от константности вашего объекта).

2

Если у вас есть указатель на объект const, это ограничит вас вызовом функций-членов const в целевом объекте.

Постоянный указатель на (нормальный) объект просто означает, что вы не можете изменить сам указатель. Поскольку это по-прежнему указатель на обычный объект, вы можете использовать любую функцию-член, а не только константные функции-члены. Если целевой объект имеет постоянные и нормальные перегрузки этой функции, будет выбрана нормальная перегрузка.

Когда у вас есть указатель в качестве члена const-объекта, вы получаете второй, а не первый.

1
По вопросам рекламы [email protected]