Вызывание функции константы от объекта неконстанты

Другой вариант, предложенный здесь здесь , устанавливает стиль изображения как style="display: block;"

21
задан Jonathan Leffler 2 January 2009 в 19:22
поделиться

10 ответов

Избегайте броска: присвойте это const Bar * или безотносительно и использование это для вызова getProcess().

существуют некоторые педантичные причины сделать это, но это также делает это более очевидным, что Вы обходитесь без того, чтобы вынуждать компилятор сделать что-то потенциально небезопасное. Предоставленный, Вы никогда не можете поражать те случаи, но Вы могли бы также записать что-то, что не использует бросок в этом случае.

10
ответ дан 29 November 2019 в 21:17
поделиться

Если бросок слишком ужасен для Вас, Вы могли бы вместо этого добавить метод к Bar, который просто возвращает ссылку константы на *this:

Bar const& as_const() const {
    return *this;    // Compiler adds "const" without needing static_cast<>
}

можно тогда звонить любой const метод в Bar только путем предварительного ожидания as_const()., например:

as_const().getProcess().doSomeWork();
3
ответ дан 29 November 2019 в 21:17
поделиться

Если бы getProcess() и getProcess() const не возвращают ссылку на тот же объект (но по-другому квалифицированный) тогда он указал бы на плохой дизайн class Bar. При перегрузке на const мыс функции не является хорошим способом отличить функции с различными поведениями.

, Если они возвращают ссылку на тот же объект тогда:

const_cast<const Bar*>(this)->getProcess().doSomeWork();

и

getProcess().doSomeWork();

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

4
ответ дан 29 November 2019 в 21:17
поделиться

const_cast для кастинга далеко constness!

Вы бросаете от неконстанты до константы, которая безопасна, так использование static_cast:

   static_cast<const Bar*>(this)->getProcess().doSomeWork();

я означаю технически говорить, можно бросить в constness с const_cast, но это не прагматическое использование оператора. Цель модернизированных бросков (по сравнению со старым броском c-стиля), должен передать намерение броска. const_cast запах кода, и это - использование, должен быть рассмотрен, по крайней мере. static_cast, с другой стороны, безопасно. Но это - вопрос стиля C++.

Или можно создать новый (частный) метод константы и вызов что от doOtherWork:

  void doSomeWorkOnProcess() const { getProcess().doSomeWork(); }

Используя временную константу также опция (ответ "MSN"):

   const Bar* _this = this;
   _this->getProcess().doSomeWork();
14
ответ дан 29 November 2019 в 21:17
поделиться

Вы не должны делать никакого обмана кастинга, если функция не перегружается. Вызов метода константы объекта неконстанты прекрасен. Это называет метод неконстанты от объекта константы, который запрещается. Если методы будут переопределены с константой и функцией неконстанты, то кастинг объекта к константе добьется цели:

const_cast<const IProcess&> (getProcess()).doSomeWork();

РЕДАКТИРОВАНИЕ: Я не считал целый вопрос. Да, Вы нуждаетесь к const_cast этот указатель или делаете константа функции doOtherWork для вызова константа IProcess& getProcess () константа .

точка остается, что Вам не нужен объект константы звонить doSomeWork. Так как это - цель, Вам нужен названный метод константы?

Другая опция состояла бы в том, чтобы переименовать переопределенные функции. Это было бы действительно хорошей идеей, если эти две функции на самом деле имеют другое поведение/побочные эффекты. Иначе эффект вызова функции не был бы очевиден.

1
ответ дан 29 November 2019 в 21:17
поделиться

Ну, можно ли объявить

void doOtherWork const ()

?

, Который сделал бы это.

0
ответ дан 29 November 2019 в 21:17
поделиться

Я предполагаю, что Вы хотите, чтобы DoOtherWork назвал один из Ваших двух вызовов getprocess в зависимости от на том, называют ли это от объекта константы или нет.

лучшее, которое я могу предложить, является этим:

class Bar
{
public:
   const IProcess& getProcess() const {return ...;}
   IProcess& getProcess() {return ...;}

   void doOtherWork {            // should use getProcess()      
    getProcess().doSomeWork();        
  }
   void doOtherWork const {
    getProcess().doSomeWork();   // should use getProcess() const     
  }
};

, Даже если это работает, это похоже на неприятный запах мне. Я очень опасался бы поведения класса, изменяющегося радикально согласно constness объекта.

0
ответ дан 29 November 2019 в 21:17
поделиться

Я думаю, что const_cast метод является Вашим наилучшим вариантом. Это - просто ограничение платформы константы в C++. Я думаю единственный способ, которым Вы могли избежать, чтобы кастинг определил метод, который возвращает константу экземпляр IProcess независимо. Например.

const IProcess* getProcessConst() const { return ... }
...
getProcessConst().doSomeWork();
0
ответ дан 29 November 2019 в 21:17
поделиться

Отправленный monjardin
Другая опция состояла бы в том, чтобы переименовать переопределенные функции. Это было бы действительно хорошей идеей, если эти две функции на самом деле имеют другое поведение/побочные эффекты. Иначе эффект вызова функции не был бы очевиден.

IProcess& получен доступ в другом коде главным образом через свойство

__declspec(property(get=getProcess)) IProcess& Process;

, настолько переименовывающее, не была опция. Большинство времени константа мыс функции вызова соответствует getProcess (), таким образом, не было никакой проблемы.

0
ответ дан 29 November 2019 в 21:17
поделиться

Вы в основном застреваете с переименованием другого метода или const_cast.

BTW, это - одна из причин, что интеллектуальные указатели копии на записи на самом деле не работают хорошо в C++. Интеллектуальный указатель копии на записи является тем, который может быть совместно использован бесконечно. Когда пользователь получает доступ к данным в контексте неконстанты, копия данных сделана (если пользователь не держит уникальную ссылку). Этот вид указателя может быть очень удобным для использования при совместном использовании больших структур данных, которые должны изменить только некоторые клиенты. Самая "логическая" реализация должна иметь константу и оператор неконстанты->. Версия константы просто возвращает базовую ссылку. Версия неконстанты делает уникальную проверку ссылки и копирование. Этому не удается быть полезным, потому что интеллектуальный указатель неконстанты будет использовать оператор неконстанты-> по умолчанию, даже если Вы хотели использовать версию константы. const_cast требование делает это очень недружелюбным пользователем.

я приветствую любого, кто доказывает меня неправильно и показывает удобный для пользователя указатель копии на записи в C++...

-1
ответ дан 29 November 2019 в 21:17
поделиться
Другие вопросы по тегам:

Похожие вопросы: