Duda en constructor copia

Iniciado por __fnx__, 30 Julio 2011, 21:20 PM

0 Miembros y 1 Visitante están viendo este tema.

__fnx__

Hola, os cuento mis paranoias con c++  :D

Código (c++) [Seleccionar]

#include <iostream>
#include <string>

using namespace std;

class CTest {
private:
int a;
public:
CTest() : a(0) {}

CTest(int d) : a(d) {}

// CTest(const CTest& obj) {
// cout << "constructor copia invocado";
// *this = obj;
// }

CTest(CTest& obj) {
cout << "constructor copia sin const invocado";
*this = obj;
}

CTest& operator=(const CTest& obj) {
a = obj.a;
cout << "operator= invocado";
return *this;
}

int getA() {
return this->a;
}
};

int main() {
       CTest miObj = CTest();  /////////////////  AQUÍ ESTÁ EL ERROR
cout << miObj.getA() << endl;

return 0;
}


El error:

../src/OtroCpp.cpp:36: error: no matching function for call to 'CTest::CTest(CTest)'

Según leo en el libro que estoy estudiando:

CTest miObj = CTest()

Es equivalente a

CTest miObj;

Ahora bien, si veis mi código, no funciona por culpa de poner el constructor copia con el parámetro no const, pero si quito los comentarios del constructor copia con const (el que implementa C++ por omisión) entonces funciona.

¿Por qué?

Y lo que me parece más raro todavía, es que al depurar el código y seguir instrucción a instrucción, veo que no llega a entrar en ningún momento en el constructor copia (en ninguno de los dos) y que se ejecuta directamente el constructor sin parámetros.

Al poner CTest  miObj = CTest() se llama al constructor copia? o no... pensando un poquito sobre el tema puedo entender con mis escasos conocimientos, que Ctest() crea un objeto sin nombre y lo copia a MiObj invocando al constructor copia, pero es que según mi depurador no es así.

En fin... ¿qué no soy capaz de ver/entender?

Gracias chic@s

leogtz

No recuerdo mucho de C++, ¿pero no sería así?


Código (cpp) [Seleccionar]
#include <iostream>
#include <string>

using namespace std;

class CTest {
private:
int a;
public:
CTest() : a(0) {}

CTest(int d) : a(d) {}

    CTest(const CTest& obj) {
        cout << "constructor copia invocado";
        *this = obj;
    }

CTest(CTest& obj) {
cout << "constructor copia sin const invocado";
*this = obj;
}

CTest& operator=(const CTest& obj) {
a = obj.a;
cout << "operator= invocado";
return *this;
}

int getA() {
return this->a;
}
};

int main() {
       CTest miObj; //CTest();  /////////////////  AQUÍ ESTÁ EL ERROR
cout << miObj.getA() << endl;

return 0;
}


Si quieres crear un puntero:

Código (cpp) [Seleccionar]
CTest *miObj = new CTest();

Saludos.
Código (perl) [Seleccionar]

(( 1 / 0 )) &> /dev/null || {
echo -e "stderrrrrrrrrrrrrrrrrrr";
}

http://leonardogtzr.wordpress.com/
leogutierrezramirez@gmail.com

__fnx__

Hola Leo, gracias por responder.

El caso es que según el libro es lo mismo.

Mira, esto también funciona:

Código (c++) [Seleccionar]


#include <iostream>
#include <string>

using namespace std;

class CTest {
private:
int a;
public:
CTest() : a(0) {}

CTest(int d) : a(d) {}

CTest(const CTest& obj) {
cout << "constructor copia invocado";
*this = obj;
}

CTest(CTest& obj) {
cout << "constructor copia sin const invocado";
*this = obj;
}

CTest& operator=(const CTest& obj) {
a = obj.a;
cout << "operator= invocado";
return *this;
}

int getA() {
return this->a;
}
};

int main() {
CTest miObj = CTest();
cout << miObj.getA() << endl;

return 0;
}



El problema está cuando quito el constructor copia que recibe la referencia al objeto constante, es decir como puse en el anterior post.

Bueno, haciendo más pruebas, si quito este constructor copia:
Código (c++) [Seleccionar]

CTest(CTest& obj) {
cout << "constructor copia sin const invocado";
*this = obj;
}


Entonces ya funciona todo normalmente.

Lo que saco en claro es que si pongo este último, tengo que poner este otro:

Código (c++) [Seleccionar]

CTest(const CTest& obj) {
cout << "constructor copia sin const invocado";
*this = obj;
}


Pero como digo, no lo llega a ejecutar (por las pruebas que obtengo depurándolo o con la ejecución, mensajes cout ).

¿Qué raro no?

__fnx__

Con Visual Studio funciona bien :xD

El_Java

A mi no me da ningun tipo de error, he uso Codeblocks en Ubuntu con g++ :)

Karman

CitarThe copy constructor takes a reference to a const parameter. It is const to guarantee that the copy constructor doesn't change it, and it is a reference because a value parameter would require making a copy, which would invoke the copy constructor, which would make a copy of its parameter, which would invoke the copy constructor, which ...

acá tenés más info.

S2