Continuando nosso artigo mutable, que raios é isso? agora irei demonstrar um segunda maneira de “burlar” o mesmo método const sem usar atributos mutáveis (mutable).
Temos a seguinte interface de exemplo, Entity (pure abstract)
class Entity
{
public:
virtual void logic() = 0;
virtual void draw() const = 0;
};
Note que classes como a acima são muito comuns em vários projetos
Agora a classe Player que implementa Entity
class Player : public Entity
{
public:
void logic()
{
}
void draw() const
{
mDrawCount++;
// Erro! pois é um método const
}
private:
std::size_t mDrawCount;
};
Mais skhaz porque não controlar isso no método logic que não é const? eu tenho bons motivos para isso, um deles é se você implementar um sistema de ticks como descrito no artigo Controle de velocidade de jogo com ticks onde quase sempre o método draw não será chamado no mesmo ciclo que logic.
ponteiro e const_cast os “vilões”
Com o uso do cast const_cast podemos burlar o atributo declarado como mutable (assim como para const e volatile) para não constantes.
void Player::draw() const
{
const_cast<player *>(this)->mDrawCount++;
// work fine =D
}
Referencia http://msdn2.microsoft.com/en-us/library/bz6at95h.aspx
Um artigo recomendado pelo nosso amigo danielf sobre mutable http://www.highprogrammer.com/alan/rants/mutable.html
Const cast é o tal recurso C++ de “hei mermão. Eu sou o programador aqui e sou eu que mando.”
Aliás, quer cast mais agressivo do que o reinterpret_cast? Você pode dizer que um monte de bytes se refere a uma classe (ou vice versa)… e voilá… acaba até com o encapsulamento.
Só lembrando que nosso amigo const_cast também consegue retirar ou colocar imutabilidade.
E ele também consegue deixar const algo que não é const.
É o caso, por exemplo, de vc querer chamar a versão const de um método a partir da sua versão não const. Exige um pouco de ginástica, já que vc vai precisar tornar o ponteiro da função um const (aí o uso do const cast), mas pode ser feito.
A dica completa está no Effective C++.