Problema con separar interfaz de implementación de una clase.

Iniciado por reethok, 25 Diciembre 2011, 11:54 AM

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

reethok

Verán, estoy estudiando C++ en el libro "C++ Cómo Programar de Deitel", y me dice que cuando creo una archivo de encabezado (.h) con una clase es recomendable definir las funciones miembro de la clase en un archivo de código fuente separado. Entonces, quedo con 3 archivos, así:

LibroCalificaciones.h

#include <string>
using std::string;

class LibroCalificaciones
{
public:
    LibroCalificaciones(string); // Constructor que inicializa a nombreCurso
    void establecerNombreCurso(string); // Función que establece el nombre del curso
    string obtenerNombreCurso(); // Función que obtiene el nombre del curso.
    void mostrarMensaje(); // Muestra mensaje de bienvenida.
private:
    string nombreCurso; // Nombre del curso para este LibroCalificaciones
};


LibroCalificaciones.cpp
#include <iostream>

    using std::cout;
    using std::endl;

#include "LibroCalificaciones.h"


// El constructor inicializa nombreCurso con el objeto string suministrado como argumento.
LibroCalificaciones::LibroCalificaciones(string nombre)
{
    establecerNombreCurso(nombre); // Inicializa nombreCurso
}

// Función para establecer nombreCurso
void LibroCalificaciones::establecerNombreCurso(string nombre)
{
    nombreCurso = nombre; // Almacena el nombre del curso en el objeto.
}

// Función para obtener el nombre del curso.
string LibroCalificaciones::obtenerNombreCurso()
{
    return nombreCurso;
}

// Muestra un mensaje de bienvenida.
void LibroCalificaciones::mostrarMensaje()
{
    cout << "Bienvenido al libro de calificaciones para\n" << obtenerNombreCurso()
        << "!" << endl;
}


Y por último, el programa cliente de la clase, Programa.cpp (soy bien creativo).
#include <iostream>
    using std::cout;
    using std::endl;

#include "LibroCalificaciones.h"

int main()
{
    LibroCalificaciones libroCalificaciones1("CS101 Introduccion a C++");
    LibroCalificaciones libroCalificaciones2("CS102 Estructuras de Datos");

    cout << "libroCalificaciones1 creado para el curso: " << libroCalificaciones1.
        obtenerNombreCurso()
        << "\nlibroCalificaciones2 creado para el curso: " << libroCalificaciones2.
        obtenerNombreCurso() << endl;

    return 0;
}


Bueno, ahora mi problema es que el libro me dice que debo compilar primero LibroCalificaciones.cpp, para así obtener el código objeto y blablabla, (NOTA, uso code::blocks con MinGW) pero al darle en compilar, me marca error. "Undefined reference to 'WinMain@16'.

Si trato de compilar "Programa.cpp", me salen los siguientes errores:


C:\Users\Nikolov\Desktop\CPP\Programa.o:Programa.c pp|| undefined reference to `LibroCalificaciones::LibroCalificaciones(std::str ing)'|
C:\Users\Nikolov\Desktop\CPP\Programa.o:Programa.c pp|| undefined reference to `LibroCalificaciones::LibroCalificaciones(std::str ing)'|
C:\Users\Nikolov\Desktop\CPP\Programa.o:Programa.c pp|| undefined reference to `LibroCalificaciones::obtenerNombreCurso()'|
C:\Users\Nikolov\Desktop\CPP\Programa.o:Programa.c pp|| undefined reference to `LibroCalificaciones::obtenerNombreCurso()'|
||=== Build finished: 4 errors, 0 warnings ===|

Y bueno, la única forma de "armar el programa" que he encontrado es crear un proyecto en code::blocks, meterle los 3 archivos y darle en "Build", y así sí funciona, pero no entiendo por qué.

¿Alguien me explica?

Y cómo le hago para hacer lo que me pide el libro, que es "ocultar la forma en que funcionan los funciones miembro al programador cliente de la clase"... osease que compilar LibroCalificaciones.cpp, y darlo ya compilado junto con LibroCalificaciones.h y así arrancar el programa en Programa.cpp?

Saludos, espero me ayuden =/

Eternal Idol

No estas compilando solamente, tambien estas enlazando, por eso te dice que para el archivo objeto (.o) no puede resolver un simbolo en particular. La unica forma de lograr compilar y enlazar eso es justamente haciendolo con los dos archivos .cpp en el mismo momento (Programa necesita la implementacion de la clase y LibroCalificaciones no tiene punto de entrada - main -).

Desde linea de comandos tambien deberia funcionarte:
g++ Programa.cpp LibroCalificaciones.cpp.
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

reethok

Entonces cómo hago lo que me pide el libro?

Dice que NO DEBO proporcionar el codigo fuente de LibroCalificaciones.cpp, sólamente el código objeto.

Eternal Idol

g++ -c LibroCalificaciones.cpp
g++ Programa.cpp LibroCalificaciones.o
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

reethok

Uso MinGW... IDE code::blocks y Windows 7... no entiendo. xD

Eternal Idol

Por lo que veo la opcion de "Compile current file" de Code::Blocks tambien enlaza ... que bazofia ... tal vez haya alguna manera de configurarlo para que haga lo que se supone dice hacer el menu pero no la conozco ni quiero aprender un IDE que nunca voy a usar.

En %Program Files%\CodeBlocks\MinGW\bin tenes el ejecutable g++, usalo desde CMD como te muestro arriba (pone los paths en los archivos al llamarlo o usa set path y llamalo desde el directorio de los archivos).
La economía nunca ha sido libre: o la controla el Estado en beneficio del Pueblo o lo hacen los grandes consorcios en perjuicio de éste.
Juan Domingo Perón

3mp3z@ndo

Para cumplir lo que te pide el ejercicio del libro, haz lo siguiente:

Primero:

g++ -c LibroCalificaciones.cpp

Segundo:

g++ -c Programa.cpp

Y por ultimo:

g++ -o Programa LibroCalificaciones.o Programa.o

Un saludo.