logo
Contato | Sobre...        
rebarba rebarba

Rodrigo Strauss :: Blog

follow us in feedly

C++11: Inicialização uniforme

Algumas mudanças no C++11 são tão grandes que têm o potencial de deixar a linguagem muito melhor, porém irreconhecível. Além do recurso de lambda (do que eu já falei) os recursos de inicialização uniforme e nova sintaxe para declaração de funções são desse tipo. Hoje vou falar sobre Uniform Initialization (ou inicialização uniforme em bom português).

O C++ tem a característica de não ser uma linguagem uniforme. Isso quer dizer que uma sequência específica de tokens pode ter significados diferentes dependendo do contexto. Isso causa diversos problemas, entre ele uma dificuldade bem maior para escrever um parser (interpretador) para a linguagem. Veja a seguinte expressão:

  1. MeuObjeto algumaCoisa(10, "lala");

Esse código pode significar duas coisas: uma declaração de função que retorna MeuObjeto ou a declaração de uma varíavel do tipo meu objeto que tem um construtor com dois parâmetros. Isso existe devido à algo que é chamado de Most Vexing Parser, ou Interpretador Mais Vexaminoso na língua de Camões. Nesse caso específico, essa linha será interpretada como uma declaração de função, algo bem inconviniente caso o trecho acima esteja dentro de uma função:

  1. class MeuObjeto
  2. {
  3. public:
  4.   MeuObjeto(int a, string b) {}
  5. };
  6.  
  7. int main()
  8. {
  9.   // Parece algo normal, mas isso é um erro de compilação
  10.   // Isso será interpretado como uma declaração de função
  11.   MeuObjeto algumaCoisa(10, "lala");
  12. }

Para resolver esse problema, entre outros, foi criada a inicialização uniforme:

  1. int main()
  2. {
  3.   // Como usamos colchetes ao invés de parenteses,
  4.   // o compilador sabe com certeza que isso é uma chamada
  5.   // de construtor (e não uma declaração de função)
  6.   MeuObjeto algumaCoisa{10, "lala"};
  7. }

Mas como sempre, a forma anterior de fazer as coisas continua valendo. Lembrem-se: o C++ tem como premissa continuar compatível com todo código fonte que já foi escrito até hoje. Essa é a maldição e a benção do C++: a linguagem evolui e fica competitiva em relação às linguagens mais novas, mas os programadores podem continuar fazendo as coisas da forma antiga e, muitas vezes, pouco recomendáveis. Um exemplo é a parte de gerenciamento de memória. Vou repetir o que digo em quase toda palestra: se você está usando new e delete você está fazendo isso errado.

O recurso de inicialização uniforme permite que toda inicialização de instâncias de objetos e estruturas usem essa nova sintaxe:

  1. // Lembrando que tipos fundamentais também aceitam
  2. // a sintaxe de construtor
  3. int i {3};
  4.  
  5. // Inclusive um construtor vazio (nesse caso i2 == 0)
  6. int i2 {}; // empty braces initialize the object to it's default (0)
  7.  
  8. // a std:string é uma classe, e aceita uma string
  9. // literal no construtor
  10. std::string s {"hello"};
  11.  
  12. MeuObjeto algumaCoisa {10, "lala"};
  13.  
  14. MeuObjeto muitasCoisas[] = { {10, "lala"}, {20, "lili"} };

É uma pequena mudança que resolve grandes problemas.

Em 17/02/2016 06:43, por Rodrigo Strauss


  
 
 
Comentários
Teston | em 20/02/2016 | #
New/delete é citado como má prática, o que eu concordo quando é feito de forma descontrolada. A alternativa é escolher entre o uso da stack ou smart pointers.

Não discordo das afirmações acima, porém eu não vejo mal em usar new/delete ou mesmo malloc/free dependendo do contexto. Exemplos de contextos válidos na minha opinião são dentro de objetos RAII ou PImpl por exemplo. Em ambos os contextos não há risco de leaks considerando implementações corretas.

Minha pergunta aqui: minhas afirmações estão corretas ou estou deixando passar algo?
Rodrigo Strauss | website | e-mail | em 22/02/2016 | #
Você tem razão, eu exagerei um pouco. Uma afirmação melhor seria que em 99% das situações não há motivos para usar new e delete.
Rodrigo Strauss | website | e-mail | em 22/02/2016 | #
Você tem razão, eu exagerei um pouco. Uma afirmação melhor seria que em 99% das situações não há motivos para usar new e delete.
Algo a dizer?
Nome:


Site:


E-mail:


Escreva o número vinte e seis:


 Não mostre meu e-mail no site, não serve pra nada mesmo...

Comentário





Os comentários devem ser sobre assuntos relativos ao post, eu provavelmente apagarei comentários totalmente offtopic. Se quiser me enviar uma mensagem, use o formulário de contato. E não esqueça: isso é um site pessoal e eu me reservo o direito de apagar qualquer comentário ofensivo ou inapropriado.
rebarba rebarba
  ::::