2009-12-22 12 views
8

Al escribir un constructor de copia para una de mis clases (que contiene algunos objetos de otras UDT), debo crear un constructor predeterminado para esos UDT, aunque en realidad nunca fueron diseñados para Toma uno.Cómo manejar el constructor predeterminado requerido

¿Está bien simplemente implementar un constructor predeterminado en blanco y terminarlo? La única vez que se invoca el constructor predeterminado es durante esta copia, cuando se crea el objeto y luego se copian los valores del objeto correspondiente. Por lo tanto, los valores que se asignan al objeto en el constructor predeterminado nunca se usarán realmente.

El problema que veo es que algunas variables miembro no se inicializan en un constructor predeterminado en blanco. ¿Debo simplemente escribir uno que dé valores falsos? ¿Alguna otra forma recomendada de manejar esto?

Editar: Entiendo que un constructor de copia NO NECESITA un constructor predeterminado si tuviera que definir constructores de copia para las otras clases, pero no lo hice, por lo que lo necesito.

+0

¡Bienvenido a StackOverflow! Gran primera pregunta. – Sampson

+0

Sería mejor con algún código de ejemplo. –

Respuesta

5

Si utiliza una lista de inicialización en el constructor de copia, no es necesario un constructor por defecto:

#include <iostream> 
using namespace std; 
class Foo { 
    Foo();   /* no default constructor */ 
public: 
    Foo(int i)  { cout << "Foo constructor (int)" << endl; } 
    Foo(const Foo& f) { cout << "Foo constructor (copy)" << endl; } 
}; 
class Bar { 
    Foo f; 
public: 
    Bar()    : f(1) { cout << "Bar constructor (default)" << endl; } 
    Bar(const Bar& b) : f(b.f) { cout << "Bar constructor (copy)" << endl; } 
}; 
int main(void) { 
    Bar b; 
    Bar b_=b; 
    return 0; 
} 

Resultados en:

Foo constructor (int) 
Bar constructor (default) 
Foo constructor (copy) 
Bar constructor (copy) 
+0

Ambas clases tienen constructores distintos al constructor de copia. Y lo que dices no es verdad. –

+0

Esa es una declaración bastante extraña. En el C++ actual, no se puede "llamar" a un constructor desde otro.Entonces, si usa el constructor de copias, simplemente * no puede * usar el constructor predeterminado (es simplemente imposible), independientemente de si está usando la lista de inicializadores o no. – AnT

+0

El punto en el ejemplo original era que el constructor predeterminado de Foo no se llamó copiando. He editado el ejemplo para eliminar el constructor predeterminado de Foo para ilustrar mejor ese punto. Obviamente, las clases tienen constructores distintos del constructor de copia: ¿de qué otra forma crearán la primera instancia del objeto? Mi entendimiento es que el objetivo es evitar agregar un constructor predeterminado no deseado. – mrkj

2

Usted dice:

cuando se crea el objeto y luego los valores del objeto correspondiente se copian en ella.

Pero pregúntese: cómo llegan los valores de ese "objeto correspondiente" en primer lugar. Es decir. ¿cómo se creó el objeto correspondiente?

This previous SO discussion pueden ayudarlo a aclarar las cosas.

4

¿De verdad está seguro de que necesita un constructor de copia? Es inusual (pero no imposible) tener una clase donde el constructor predeterminado estaría bien, pero necesita un constructor de copia personalizado. ¿Tal vez podrías publicar el código para tu clase?

+0

Sí, porque necesito hacer una copia profunda. – Anonymous

+0

C++ realmente no usa el término "copia profunda" - las cosas estarían mucho más claras si publicaras algún código. –

+0

Bueno, ¿cómo se llama si no se llama copia profunda? – Anonymous

1

Esto no suena como la mejor manera de implementar un constructor de copia. Si los tipos contenidos proporcionan constructores de copia, utilícelos. Puede haber una razón por la cual un tipo no proporciona un constructor predeterminado después de todo.

1

quisiera en primer lugar preguntar por qué copiar esos UDT implica el defecto constructor, en lugar de la copia más apropiado constructor. También me preguntaría qué significa para un objeto estar en el predeterminado estado inicializado — si significa algo, entonces impleméntelo.

Si no tiene un significado razonable para una inicialización predeterminada, y tiene que definir el objeto usando un constructor predeterminado, supongo que se puede implementar un constructor predeterminado.

Sin embargo, no todos los objetos pueden obtener un constructor predeterminado, por lo que es una buena idea arreglar el origen del problema.

0

Puede evitar que el constructor predeterminado requiera que el otro objeto tenga también constructores de copia (o use un constructor especial que pase toda la información necesaria para construir los objetos. Generalmente tener un constructor predeterminado que no inicialice todas las variables miembro es muy mala idea. Como mínimo, asegúrese de que los constructores por defecto de la otra clase inicialicen todos los miembros.

3

Me parece que necesita definir códigos de copia para las otras clases, ya que está creando objetos al copiar otros objetos.

0

Recuerde que una regla del pulgar que en cuanto a algo no es parte de la especificación, el compilador no lo hará por usted.

Si su clase contiene un tipo definido por el usuario y cuando crea un objeto del mismo, el compilador debe llamar al constuctor predeterminado para cada objeto.

Pero para inicializar los datos de los miembros no es una tarea del compilador, pero se supone que debes hacerlo.

Para el caso que ha mencionado, necesita su propio constructor de copia personalizado y operador de asignación.

0

Si no desea que el compilador genere un constructor de copia o no desea un constructor de copia, declare un constructor de copia privada pero no le proporcione ninguna definición (código). El compilador verá las declaraciones y no generará una. También haga esto con el operador de asignación.

Hago esto con mis clases singleton.

0

Si su clase no debe construirse de manera predeterminada, no cree un constructor predeterminado. Si es así, entonces estoy seguro de que puede encontrar una inicialización razonable, así que eso es lo que debería estar usando.

0

La pregunta, la forma en que lo dijiste, parece no tener sentido. Copy-constructor no necesita el constructor predeterminado, como parece creer. Copy-constructor es un constructor completo completamente independiente que construye un objeto completamente por sí mismo.

Si construyes tus objetos con copy-constructor, entonces no necesitas uno por defecto. Si construye sus objetos con el constructor predeterminado, entonces no puede usar el constructor de copias en ellos. No es posible "aplicar" dos constructores diferentes al mismo objeto.

Si construyes tus objetos de ambas maneras, se convierten en dos constructores completamente independientes, cada uno de los cuales tiene su propio propósito independiente. En este caso, la pregunta que debe hacerse es cómo desea que sus objetos sean construidos de forma definitiva. Solo tú lo sabes.

De nuevo, necesita aclarar su pregunta. Sospecho (por su descripción) que tal vez lo que está tratando de implementar no es un constructor de copias, sino un operador de asignación de copias. Pero eso es solo una suposición salvaje.

Cuestiones relacionadas