Const указатель на метод, который делегирует метод removeAll () - PullRequest
2 голосов
/ 01 сентября 2010

Рассмотрим метод, подобный этому:

void Parent::removeChild(Child *child)
{
    children.removeAll(child);
}

В этом случае, поскольку child никогда не изменяется сам, можно сделать его константным указателем.Но поскольку children относится к типу QList, метод removeAll () принимает константную ссылку на указатель non-const .

Какой рекомендуемый способ обработки этого?Пропустить постоянство аргумента метода или const_cast указатель const, чтобы соответствовать методу removeAll ()?

Ответы [ 3 ]

1 голос
/ 03 сентября 2010

Хитрый. Вы должны были добавить еще немного кода, но из документов я предполагаю, что у вас есть QList<Child*> и вы не можете изменить его на QList<const Child*>, потому что вам нужен неконстантный доступ к фактическим объектам .

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

0 голосов
/ 03 сентября 2010

Похоже, QList предназначен для использования с указателями.Они определяют большую часть интерфейса, который является константой, как const T&, который отлично работал бы, если бы ваш QList был на Child, а не Child*.

. Он будет работать с указателями просто отлично, но этоне могу заявить, что constness подходит для них.Я не рекомендую менять свой QList на Child, если его копирование не обходится дешево, у вас есть вся необходимая семантика для копирования ctor, dtor, op =, op == и т. Д., И вы не против иметь копии в списке, а необъекты, которые вы передаете. Вы можете видеть, как с int или строками, что он будет работать как положено (removeAll будет const правильным).

Если правильность const важна для вас, тогда используйте const_cast.Затем объявите const ref и передайте его.

void Parent::removeChild(const Child *child)
{
    QList<Child*>::const_reference constRefToChild = const_cast<Child *> child;
    children.removeAll(constRefToChild);
}

Смысл в том, что если removeAll когда-либо изменяется, чтобы не принимать const, вы получаете ошибку компилятора.Тогда вы знаете, что removeAll не сохраняет константу аргумента.

0 голосов
/ 01 сентября 2010

Если вы хотите сказать, что изменение списка детей не является изменением экземпляра Parent, просто создайте список детей mutable.

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

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

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

...