Предотвращение дублирования кода (const -корректность) redux - PullRequest
1 голос
/ 26 сентября 2010

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

Один из возможных обходных путей, который мне приходил в голову, заключался в простой передаче ссылки на this в функцию const в качестве параметра, поэтому функция может использовать эту ссылку вместо прямого использования указателя this. Но это безопасно? Это кажется безопасным (хотя и очень хакерским), потому что вы на самом деле не используете const_cast для const-объекта. Скорее вы просто обойдете договор, предоставленный функцией-членом const, передав ему неконстантную ссылку на объект.

Например:

class Foo
{
    private:

    template <class SelfReference>    
    void f1(SelfReference& self) const
    { 
        // We now might have a non-const reference to "this", even though
        // we're in a const member function.  But is this safe???
    }

    public:    

    void f2()
    {
        f1(*this);
    }

    void f2() const
    {
        f1(*this);
    }
};

Похоже, это хороший способ избежать дублирования большого количества кода, когда требуется постоянная и неконстантная версия функции, но безопасно ли это? Или это как-то вызывает неопределенное поведение?

1 Ответ

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

Обратите внимание, что даже если вы находитесь в функции const f1() и можете изменить «this», f2() помечается как неконстантное, поэтому при вызове f2() объект может быть изменен.И только f1() не позволит вам изменить «это» внутри себя (или любого объекта const).Вы даже не можете вызвать f2() в помощь const Foo объекту, так что это не принесет никакой пользы.

Другими словами - в вашем примере неконстантного f1() будет достаточно.Вам не нужно f1() const или обе версии здесь.


ОБНОВЛЕНИЕ Теперь вы не сможете изменить self в "const" версии f1()void f1(const Foo & self) const вызывается из void f2() const.

...