2
Tiempo::Tiempo(const Tiempo &t){
hms=t.hms;  //  Esta Linea no Comprendo exactamente que 
                  // es lo que hace, que es lo que le digo que realize
}
  1. hms es una Variable que contiene una Hora
  2. Recien Estoy Aprendiendo Sobre constructores, y no quisiera quedarme con esa duda, muchas Gracias de Antemano.
eferion
  • 49,291
  • 5
  • 30
  • 72
KinEC93
  • 23
  • 3

2 Answers2

1

Los constructores son unas funciones especiales dentro de C++ que se invocan de forma automática en determinadas circunstancias.

Así, como norma general, el constructor por defecto se invocará automáticamente al declarar un nuevo objeto sin argumentos:

Tiempo t; // Se invoca el constructor por defecto.

Pues bien, el constructor copia sirve para inicializar un objeto a imagen y semejanza de otro ya existente. Es decir, sirve para hacer una copia de otro objeto. Así, el siguiente ejemplo crea un objeto t2 copia de otro ya existente (t1):

Tiempo t1;
// ...
Tiempo t2 = t1; // Constructor copia

El constructor copia, como bien has puesto en la pregunta, recibe como único argumento un objeto del mismo tipo que el que vas a crear:

Tiempo::Tiempo(const Tiempo &t)
//                   ^^^^^^

Aquí es importante remarcar que el constructor no debe (lo normal es que el programa no compile) recibir una copia sino una referencia... si recibiese una copia entrarías en un bucle sin fin ya que para invocar al constructor copia tendrías que crear antes una copia del argumento... que obligaría a llamar al constructor copia y así indefinidamente.

Superado este trámite, el constructor copia recibe una referencia al objeto que debe copiar. Llegados a este punto lo único que debe hacer el constructor copia es copiar el estado (las variables miembro) del objeto que recibe como argumento. En el ejemplo de tu pregunta, la clase Tiempo solo tiene una variable miembro hms y el constructor copia se limita a copiarla.

Puede haber situaciones en las que el constructor copia no pueda limitarse simplemente a copiar datos... es lo que sucede, por ejemplo, al usar memoria dinámica:

class Test
{
  int* ptr;

public:
  Test()
    : ptr(new int[10])
  { }

  ~Test()
  { delete[] ptr; }
};

En este caso, si el constructor copia se limitase a copiar el puntero sucederían dos problemas:

  • Perderías la referencia a una región de memoria reservada (fuga de memoria).
  • Acabarías haciendo un borrado doble cuyo comportamiento es indefinido (normalmente el sistema operativo mata tu programa).

Así pues, en estos casos la funcionalidad del constructor copia es algo más compleja, como por ejemplo:

Test::Test(Test const& t)
  : ptr(new int[10])  // Se hace una nueva reserva de memoria
{
  // Se copia el contenido de t.ptr en this->ptr
  std::copy(t.ptr,t.ptr+10,ptr);
}
eferion
  • 49,291
  • 5
  • 30
  • 72
1

El constructor de copia, como su nombre indica, se usa para copiar los datos de un objeto a otro objeto (del mismo tipo) que se esté construyendo. El estándar de C++ nos describe el constructor de copia en punto 12.8.2 (traducción mía):

12.8.2 Copiar y mover objetos clase

Un constructor no-plantilla para la clase X es un constructor de copia si su primer parámetro es de tipo X&, const X&, volatile X& o const volatile X& y o bien no tiene otros parámetros o el resto de parámetros tiene argumentos por defecto. [Ejemplo: X::X(const X&) y X::X(X&,int=1) son constructores de copia:

struct X {
    X(int);
    X(const X&, int = 1);
};
X a(1); // llama X(int);
X b(a, 0); // llama X(const X&, int);
X c = b; // llama X(const X&, int);

fin del ejemplo ]

Conceptualmente el objeto en construcción no tiene ningún motivo para modificar el objeto que está copiando, por eso el parámetro recibido suele ser constante:

Tiempo::Tiempo(const Tiempo &t){
// constante ->~~~~~
}

Aunque el estándar no prohíbe que no sea constante.


La línea de la que tienes dudas está copiando el miembro Tiempo::hms del objeto recibido por parámetros (t.hms) en el miembro Tiempo::hms del objeto que se está construyendo:

Tiempo::Tiempo(const Tiempo &t){
    hms=t.hms;
//  ^^^   ^^^
//   |     \- Este 'hms' pertenece a 't', que es el objeto recibido como argumento.
//   |
//   \- Este 'hms' pertenece al objeto que se está construyendo.
}

Suponiendo que Tiempo sólo tenga un miembro llamado hms, estarías copiando todos los datos de una instancia (t) en la instancia que se está construyendo. Para constructores tan sencillos como este, se puede pedir al compilador que cree el constructor por ti:

struct Tiempo {
    // Le pido al compilador que cree por mi el constructor de copia.
    Tiempo(const Tiempo &) = default;
private:
    unsigned long long hms = 0ull;
};
PaperBirdMaster
  • 44,474
  • 6
  • 44
  • 82
  • Muchas Gracias, me quedo muy claro.!! – KinEC93 Jun 25 '18 at 13:04
  • @KinEC93, como información adicional, puedes ver documentación de C++ en español en: https://es.cppreference.com/w/ La documentación relevante para los contructores de copia: https://es.cppreference.com/w/cpp/language/copy_constructor Todo lo que se refiere a inicialización se encuentra aquí: https://es.cppreference.com/w/cpp/language/initialization – jestrada Jun 04 '20 at 00:38