Ponto V!

Home C/C++ Smart Pointers Smart Pointers Type Casting
Bruno Crivelari Sanches
Smart Pointers Type CastingImprimir
Escrito por Bruno Crivelari Sanches

Vimos o type casting que o C++ herdou do C neste tutorial e vimos também as novidades do C++ neste outro tutorial, neste tutorial vamos ver como realizar casting com os smart pointers da Boost , estes operadores podem ser usados com o shared_ptr e o intrusive_ptr.

Mas primeiramente, porque existem operadores de cast específicos da Boost? Pelo fato de que os operadores do C++ não estão preparados para lidar com smart pointers e contagem de referências, dessa forma, caso se utilize um operador padrão do C++ a contagem de referência do objeto pode se tornar invalida, resultando em um objeto sendo destruído mais de uma vez. Exemplo:

enum Eventos_e 
{ 
    TIRO, 
    ABRIR_PORTA 
};

class Objeto 
{ 
    public: 
        virtual void Evento(int tipo, void *param) = 0; 
        virtual void Atualizar()=0; 
};

class Monstro: public Objeto 
{ 
    public: 
        virtual void Evento(int tipo, void *param); 
        virtual void Atualizar(); 
        
    private: 
        int m_energia; 
};

Com base na hierarquia acima, vamos criar alguns objetos e fazer um cast:

int main(int, char **) 
{ 
    using namespace boost; 

    shared_ptr<Objeto> obj(new Monstro()); 
     
    shared_ptr<Monstro> monstro(static_cast<Monstro*>(obj.get()));    
}

Repare que na linha onde é feito o cast é usado o método get do shared_ptr para se obter uma referência ao objeto que obj armazena, depois é feito o cast e o ponteiro resultante é utilizado para inicializar o ponteiro "monstro", note que monstro foi inicializado com um ponteiro comum, não com outro shared_ptr, ou seja, para o shared_ptr "monstro" ninguém até o momento gerenciava esse ponteiro, então ele vai simplesmente começar uma nova contagem de referências, dessa forma, quando a função terminar de executar, ambos os smart pointers vão destruir o objeto Monstro, resultando em um comportamento indefinido.

Para evitar esses problemas foram criados os casts a seguir:

Cada um dos casts acima deve ser usado nas mesmas situações dos casts do C++, a diferença é que eles devem ser apenas usados quando os objetos envolvidos são gerenciados por smart pointers.

No caso do exemplo anterior, o código correto é listado abaixo:

int main(int, char **) 
{ 
    using namespace boost; 
    shared_ptr<Objeto> obj(new Monstro()); 
     
    shared_ptr<Monstro> monstro(static_pointer_cast<Monstro>(obj));    
}

Note que as operações de cast da boost são idênticas as do C++, a diferença é o nome do operador usado.

As operações de cast da Boost devem ser sempre usadas quando é necessário fazer casts entre ponteiros gerenciados por smart pointers da mesma, nos outros casos, deve-se utilizar os operadores do C++.


Comentários (2)
  • Neto  - ?
    avatar

    É impressão minha ou tem um parentese a mais na linha 7 do ultimo exemplo ?

    shared_ptr monstro(static_pointer_cast(obj)));

    Num deveria ser "shared_ptr monstro(static_pointer_cast(obj));" ?

  • Bruno Crivelari Sanches
    avatar

    O parêntese estava errado mesmo, mas pior que ta cheio de erros no código, estão faltando os tipos nos casts, corrigido! Valeu!

Escrever um comentário
Your Contact Details:
Gravatar enabled
Comentário:
[b] [i] [u] [url] [quote] [code] [img]   
:angry::0:confused::cheer:B):evil::silly::dry::lol::kiss::D:pinch::(:shock:
:X:side::):P:unsure::woohoo::huh::whistle:;):S:!::?::idea::arrow:
Security
Por favor coloque o código anti-spam que você lê na imagem.
LAST_UPDATED2  

Busca

Linguagens

Twitter