logo
Contato | Sobre...        
rebarba rebarba

Rodrigo Strauss :: Blog


Mais explicações sobre copy constructors

Aquele post sobre copy constructors gerou para mim uma dúvida existencial: por que o compilador os gera automaticamente? Não é lá muito comum que os compiladores C++ gerem código.

Depois procurar no FAQ do Stroustrup e não encontrar, resolvi perguntar aos gurus do comp.lang.c++.moderated. Se eles não soubessem, nem o próprio Stroustrup saberia, e eu continuaria até o fim dos meus dias com o peso da dúvida sobre os ombros. As respostas foram muito interessantes.

Em 11/04/2005 21:35, por Rodrigo Strauss


  
 
 
Comentários
Thiago Adams | website | em 12/04/2005 | #
O livro The Design and Evolution of C++, do Stroustrup tem todas as dúvidas filosóficas do C++.
Infelizmente nunca li este livro, mas já vi referência para ele em vários lugares sempre quando se tem uma dúvida do tipo "porque c++ é assim".

O copy contructor é uma solução para compatibilidade com o C. Acho que ele se enquadra bem no C++ e faz todo sentido.

Li algumas respostas do comp.lang.c++.moderated.
Interessante que lá tinha um exemplo de algo que eu faço, que é inicialização de variáveis assim:

int i(0);
double d(0.0);
double d = double();

Para templates é útil também pois você pode não saber o valor default do tipo. Daí basta colocar TIPO();
template<class T>
class X {
T value;
X () : value(T()) {}
}

Este conceito falha no caso de enums, para compatibilidade com o C.

enum E { a = 1, b = 2 };
E e = E();
não fica como 1 e sim com 0.
Rodrigo Strauss | website | em 12/04/2005 | #
Eu acho que ele faz todo sentido, mas queria saber porque ele é gerado automaticamente, já que isso pode causar bugs e não é algo comum em C++.

Alguém lá da comp.c++ disse que era para ficar mais parecido com os tipos básicos, mas alguém lá mesmo retrucou dizendo "se é assim, onde está meu operator+(X&) automático?" :-)
Thiago | em 14/04/2005 | #
Este bug aconteceu comigo na prática.
Achei que estava chamando um construtor..e na verdade estava chamando o construtor default.

struct A {};
class Utils
{
// Utils(const Utils &) ; //<-- p/ confirmar
A &m_a;
public:
Utils(A &a) : m_a(a) {
std::cout << "Hello!" << std::endl;
}
};

struct B : public A,
public Utils
{
//achei q estava chamando Utils(A &a)
B() : Utils(*this) {}

//B() : Utils((A&)*this) {} //<- solucao
};

int main(int argc, char* argv[]) {
B b;
}

*No caso real A era um CDialog, B era uma classe Derivada de um CDialog e Utils era um conjunto de funções utilitárias que precisavam de uma referencia para um CDialog.
rebarba rebarba
  ::::