Pergunta

Cumprimentos a todos!

Tenho uma classe que recebe um ponteiro para um "círculo" (por exemplo) e depois ajusta seus atributos através de alguns métodos de "encadeamento".Algo assim:

class CCircleSetter
{
public:
   explicit CCircleSetter( CCirclePtr circle ) : m_circle(circle)
   {
   }

   CCircleSetter & Radius( int radius )
   {
       if (m_circle) m_circle->SetAttribute( "radius", radius );
       return *this;
   }
   CCircleSetter & Center( CPoint center )
   {
       if (m_circle) m_circle->SetAttribute( "center", center );
       return *this;
   }

   operator bool() const
   {
      return ( m_circle != NULL );
   }

private:
   CCirclePtr m_circle;
};

Agora me pergunto se este código é legal ou não:

if ( CCircleSetter(myCircle).Radius(10).Center(myPoint) ) 
{ ... }

Por um lado, acho que aquele objeto temporário, criado dentro da expressão "if", viverá até o final desta expressão.Portanto, as chamadas para “Radius” e “Center” são legais.Mas, por outro lado, é um comportamento indefinido usar referências a variáveis ​​temporárias e me parece que estou fazendo exatamente esse tipo de coisa - usando (*this), onde "this" é temporário.Isso me dá algumas dúvidas, então, por favor, esclareça.Obrigado!

Foi útil?

Solução

Não, tudo bem neste caso muito específico, porque o temporário será destruído APÓS a execução de toda a linha, mas em geral é muito ruim manter referências a temporários.

Outras dicas

Mesmo que seja uma variável temporária, isso não significa que todos os seus membros sejam temporários.Dentro do escopo do seu objeto temporário, o this ponteiro e outros membros não são temporários.Seu código está perfeitamente correto.Agora, se você fez algo como:

SomeFunc(&CCircleSetter(myCircle))

isso seria uma referência a uma variável temporária.

Não creio que uma referência a um temporário seja indefinida, é apenas proibida.Além disso, acredito que isso se aplica apenas a argumentos de função.O Visual Studio permitirá que você passe referências a temporários não const no nível de aviso/erro padrão, embora eu saiba que o gcc não o fará.

Pelo que eu sei, isso só é proibido para que os programadores não dêem um tiro no próprio pé ao armazenar uma referência a um temporário que sai do escopo.Considerando que se trata de C++, acho isso bastante estúpido.

Não vejo nenhum problema com o que você está fazendo.

O que você está fazendo é basicamente o mesmo que em

if( istrm >> a >> b ) ...

que é o mesmo que

if( istream.operator>>(a).operator>>(b).operator some_bool_like_type() )

Acho que isso é bom do ponto de vista da usabilidade.(Certamente não há problemas sintáticos/semânticos com isso.)

No entanto, como sempre, a conversão implícita para bool é um pouco desagradável, porque permite a compilação de código inesperado:

if ( CCircleSetter(myCircle).Radius(10) != 10 )
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top