Pergunta

Estou um pouco confuso quanto à mecânica do construtor de cópia. Corrija-me se eu estiver errado:

Se um método leva uma referência a um objeto como um parâmetro, e a classe define um construtor de cópia, então a classe usa o construtor para criar uma cópia de si mesmo e que é passada para a função em vez de uma referência ao original objeto?

Além disso, pode-se chamar

Object * obj = new Object(&anotherObject);

para criar uma cópia de anotherObject?

Foi útil?

Solução

Não, se uma função de dar uma referência:

void f1( Object & o );   // call by reference

, em seguida, nenhuma cópia é feita. Se uma função tem um valor:

void f2( Object o );   // call by value

, em seguida, uma cópia é criada pelo compilador usando o construtor de cópia.

E sim, quando você diz:

Object * obj = new Object(anotherObject);   // not &anotherObject

o construtor de cópia é usado explicitamente (assumindo anotherObject é do tipo Object.) Não há nada mágico sobre o uso de new aqui, no entanto - neste caso:

Object obj2(anotherObject);

o construtor de cópia também é usado.

Outras dicas

Se um método leva uma referência a um objeto como um parâmetro , construtor de cópia não será chamado. Se fosse esse o caso, então uma chamada para o próprio construtor de cópia teria resultado em um loop infinito (uma vez que leva uma referência como um argumento).

Essa linha não é uma forma válida para chamar um construtor de cópia. Ele espera uma referência como um argumento, não um ponteiro.

O fato de que você está fazendo uma chamada de método não é importante aqui. inicialização parâmetro de referência durante uma chamada de função não é diferente de uma inicialização de referência autônomo e é regido pelas mesmas regras.

As regras de inicialização de referência são um pouco complicado, mas a linha de fundo é que se o inicializador é um lvalue (o argumento na chamada de método no seu caso) e o tipo de referência é o mesmo que o tipo de inicializador (isto é, tipo do parâmetro é o mesmo que o tipo de argumento), em seguida, a referência será ligado directamente. Ou seja, não é criada cópia.

Object a; // class type
Object &r = a; // no copying
const Object &cr = a; // no copying

Se estes requisitos não forem cumpridos (como se o inicializador é um rvalue, por exemplo), então tudo depende. Em alguns casos, a cópia pode e terá lugar. Por exemplo

const Object &tr = Object();

pode ser interpretado pelo compilador como

const Object &tr = Object(Object(Object(Object())));

com número finito dependente da implementação de copyings. Claro que, por razões de eficiência compiladores normalmente não são tentando criar cópias desnecessárias, mesmo quando eles estão autorizados a copiar.

Um exemplo clássico que muitas vezes agita debate sobre a validade do comportamento copiando do compilador é a inicialização de referência em expressões como a seguinte

Object a;
const Object &r = <some condition> ? a : Object();

Uma pessoa familiarizada com semântica de referência C ++ iria entender que as expressões como o acima são susceptíveis a lógica por trás a permissão padrão para realizar a cópia supérfluo durante a inicialização de referência.

Não em ambos os casos. No primeiro caso, referência a esse objeto em si é passado e cópia não é criado. No segundo caso, você está passando um ponteiro para o construtor de object, portanto, nenhuma cópia é criada. Então objeto deve ter um construtor (não é um construtor de cópia), que é algo como object(anotherClass*)

construtor

Copiar só é chamado quando passar por valor , não por referência . Por referência não é necessária nenhuma cópia (isto é parte do que referências são para!) Assim, não construtor de cópia chamado.

sim usando posicionamento novo assim:

Object dstObject;
new(&dstObject) Object(&anotherObject);
Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top