[C con Clase] Duda sobre ejercicio

Davidson, Steven srd4121 en njit.edu
Sab Nov 3 17:46:23 CET 2012


Hola Miguel Alejandro,

2012/11/3 Miguel Alejandro Jimenez Ramirez <cerberbero en gmail.com>:
> Hola a todos espero que esten bien , buneo el dia de hoy queria enviar
> un ejercicio , por que tengo unas dudas; el programa es el siguiente:
>

[CORTE]

>
> Al ejecuterlo , sale 245
>
>
> Buneo , mis preguntas son:
>
>
> 1. Entiendo el primer 2 , pero por uque se vuelve a entrar al
> constructor copia al llamar a la funcion:
>
> A g(const A a) { return a; }
> ////
> cuando hago la asignacion:
>
> b=g(c);
>
> se vuelve a acceder al constructor copia dos veces mas ,, entonces me
> pregunto yo , es que cuando la funcion g , recibe como parametros una
> clase tipo A , en este caso c , se vuelve a crear el constructor
> copia?
>

Recuerda que en C++, por defecto, los parámetros se pasan por copia (o
por valor). En el caso de 'g()',

A g( const A a )  { return a; }

realmente hacemos esto:

const A a = c;  // Instanciamos 'a' con 'A::A(const A &)'  (el
constructor copia)
return a;

Pero, retornamos un objeto de la clase 'A', lo cual significa que
tenemos otro objeto a instanciar. Al final, obtenemos un código que se
comporta así:

const A a = c;  // 1ª llamada al constructor copia
A __retorno__ = a;  // 2ª llamada al constructor copia
return __retorno__;

Esto implica que la siguiente sentencia será:

b = __retorno__;

Por cierto, '__retorno__' es la variable "escondida" y controlada por
el compilador, para implementar el mecanismo de retorno de una
función.

> 2.cuando hago la de claracion de la clase d ,
>
> const A& d = f(c);
>

En estos casos, es mejor que usemos la terminología correcta, por lo
que deberíamos decir, "definimos (e inicializamos) una referencia a un
objeto de la clase 'A' que es constante o que será tratado como tal".

> no entiendo por que se llama al constructor copia una vez , ya que la
> funcion f devuelve una clase A , y los parametros que recibe es la

Nuevamente, es mejor que usemos la terminología correcta: "...devuelve
un objeto de la clase 'A'...".

> referencia de una clase A en este caso c , es decir no me queda claro
> como se cuando llamo al constructor copia , en que casos
>
> A f(const A& a) { return a; }
>

Bueno, esto lo he explicado en el apartado #1. Al retornar un objeto
de la clase 'A', realmente estamos creando un objeto. En este caso,
instanciamos este objeto a retornar a partir del objeto, el cual se
referencia mediante 'a'. Es decir, tenemos esto,

A __retorno__ = a;  // Llamada al constructor copia: 'A::A(const A &)'
return __retorno__;

lo cual implica la sentencia:

const A& d = __retorno__;



> 3. Otra pregunta respecto a este ejercicio , es la siguiente , el tipo
> de almacenamiento explicit , no esta explicado en el curso entonces ,
> me gustaria saber cuando se utiliza , y cual es su funcionalidad , si
> me pueden ayudar conesto les agradeceria.
>

El vocablo 'explicit' se usa únicamente con los constructores. Sirve
para indicar que tal constructor no será invocado implícitamente. En
tu programa, no podríamos hacer esto:

A func()  { return 5; }

Implícitamente el compilador haría esto:

A __retorno__( 5 );
return __retorno__;

Sin embargo, hemos indicado que este constructor es explícito, por lo
que nos veríamos forzados a usar el constructor explícitamente
escribiendo esto:

A func()  { return A(5); }

>
>
> Bueno  esas son las preguntas de este ejercicio , pero tengo otras ,
> respecto al apuntador this,
>
>
> PREGUNTAS RESPECTO AL APUNTADOR THIS.
>
>
> En el curso hay un capitulo donde hablan de constructores virtuales ,
> utilizan una funcion para clonar una clase , en eseta aprte hacen una

Cuidado con la terminología. No estamos clonando una clase, sino un objeto.

> llamada a una funcion para clonar la clase , la verdad no entiendo muy
> bien , por que el programa es el siguiente:
>
>

[CORTE]

>
> Cuando se declara la funcion :
>
>    virtual Persona* Clonar() { return new Persona(*this); }
>
> entonces , es virtuel y es un apuntador a Persona , lo que retorna es
> un espacio de memoria para Persona ?, es decir en que momento cuando
> se llama a esta funcion desde el main

La dirección de memoria que retorna es la misma que nos proporciona el
operador 'new' en la sentencia 'return'.

> por que yo entiendo que el constructor copia es como una funcion:
>
> Clase(const Clase &objeto){ instrucciones }
>

Bueno, el constructor copia ES una función, aunque algo peculiar.

>
> y en esta funcion clonar retorna es :
>
> Clase(Clase *ptr);
>

La función 'Clonar()' es una función miembro; no es un constructor,
como decimos en el curso, "Los constructores no pueden ser virtuales".
La llamamos "constructor virtual" porque se comporta como un
constructor.

La forma de usar esta función miembro es como cualquier otra. Por ejemplo,

int main()
{
  Persona *pPepe = new Persona( "Pepe" );
  Persona *pCopia = pPepe->Clonar();
  ...
  delete pCopia;
  delete pPepe;

  return 0;
}


Espero haber aclarado todas las dudas.

Steven




Más información sobre la lista de distribución Cconclase