2010-08-31 4 views
2

Рассмотрим метод, как это:Const указатель аргумент метода, который делегирует RemoveAll()

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

В этом случае, так как ребенок никогда не модифицируется сам, один может сделать это константный указатель. Но так как дети имеют тип QList, removeAll() принимает константу ссылки на указатель неконстантный.

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

+0

Когда вы говорите «const pointer», вы имеете в виду 'const Child *' или 'Child * const'? Когда вы говорите, что «const ссылается на неконстантный указатель», вы имеете в виду «Child * const &» или что-то еще?Существует внутренняя неоднозначность, потому что «const pointer» строго означает «T * const», но в случайном использовании может означать «const T *». –

+0

Извините за путаницу. Я имею в виду «указатель на const Child» для аргумента, в то время как 'removeAll()' будет принимать «константную ссылку на указатель на неконстантный ребенок». Я всегда забываю, какой синтаксис есть. Поэтому я говорю не о самом значении указателя, а о том, на что указывает ребенок. –

+0

Я не понимаю. Что такое QList, что он делает и откуда он? –

ответ

1

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

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

+0

Теперь вот что я просил :) –

0

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

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

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

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

+0

в дополнение к тому, что @Billy сказал, 'mutable' позволяет использовать метод' const' для записи данных, отличных от 'const'. Он * не позволяет * метод, который принимает параметр 'const T *', чтобы передать его в 'T *'. –

+0

", то просто сделайте список детей изменчивым." Это член, которого я предлагаю сделать изменчивым, если это желаемая семантика. Факт заключается в том, что требуемый приказ показывает, что Эмиль Эрикссон не хочет, чтобы класс Родитель считался «измененным», если его члены «дети» (QList AFAIU) изменены. Поэтому, чтобы сделать его функцию const, он действительно должен сделать этот список изменчивым ИЛИ предположить, что изменение списка действительно меняет родителя. В противном случае, const casting - это патч, который только сделает вещи неочевидными для пользователей класса. – Klaim

0

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

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

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

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

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

 Смежные вопросы

  • Нет связанных вопросов^_^