Entonces, primero en :
Empleado
empleado12;
Se instancia un objeto de la clase Empleado con nombre
empleado12. Entonces empleado12 tiene la estructura de la clase
Empleado.
Luego, en las líneas siguientes a la instanciación del objeto,
se le asignan los valores iniciales a sus variables:
//asignacion de valores a las variables
miembro
empleado12.SetNombre("Jose");
empleado12.SetDepartamento("Sistemas");
empleado12.SetPosicion("Programador");
empleado12.SetSalario(3000000);
Finalmente se llama ImprimirInfo para
imprimir el contenido de las variables:
//impresion de los datos
empleado12.ImprimirInfo();
que lo que hará es imprimir el valor de las
varibles en la pantalla.
Permitir el acceso a las variables solo a travez
de funciones, que en la mayoría de los casos se llaman SetXxx y GetXxx, se llama encapsulación de datos. Las funciones que
necesitan valores de otra clase, llaman a las funciones que les dan acceso y
obtienen estos datos sin conocimiento de detalles específicos de como se
manipulan los datos.
El operador de ambito permíte acceder de otra manera funciones de miembro y variables de miembro de una clase. Cuando aparece el operador de resolución de ámbito entre el nombre de la clase y el nombre de la función en un programa significa que la función especificada es un miembro de la clase especificada:
Empleado::ImprimirInfo();
El operador de resolución de ambito se suele utilizar para llamar funciones que se encuentran fuera del ambito de la función de llamada. Entonces, para llamar la función ImprimirInfo() de la clase Empleado se fuera de su ambito se debe utilizar este operador.
La principal diferencia entre este operador y los operadores punto y flecha es que el operador de resolución de ambito se utiliza para acceder a miembros de clases, y el operador punto y flecha para acceder a miembros de objetos específicos.
Veamos el siguiente código:
::MessageBox("Prueba del operador de resolucion");
Si el operador de resolución de ambito aparece sin un nombre de clase delante, significa que la función que esta llamando ( MessageBox ) no es miembro de ninguna clase.
Este apuntador lo tiene todo objeto en C++, apuntando a sí mismo. Se puede utilizar este apuntador en cualquier lado para acceder a todos los miembros del objeto al cual esta apuntando este apuntador this. Veamos el siguiente código:
#include <iostream.h>
class Miclase {
public:
Miclase() {} //constructor por defecto
~Miclase() {} //destructor
void yoMismo() { return this }
};int main()
{
void* pClase;
Miclase unObjeto;
pClase = unObjeto.yoMismo();
cout<< "El puntero pClase es "
<< pClase <<'\n.';
return 0;
}
En este ejemplo la clase yoMismo() devuelve un apuntador al objeto que
lo posee de la clase Miclase. El main() crea un objeto de la clase Miclase
y luego llama a yoMismo(). Lo almacena en pClase y luego enseña el contenido,
que en este caso es el valor de la referencia. Entonces este apuntador
nos permitira realizar muchas cosas sobre los propios objetos con esta
referencia.
Cuando una clase se deriva a partir de una clase base, la clase derivada hereda todas las variables de miembro y funciones de miembro de su clase base.
El siguiente código muestra como se puede derivar una clase a partir de una clase base en un programa en c++ y define una jerarquía sencilla.
#include <iostream.h>
//clase base
class EmpInfo {
public:
//constructor y destructor
EmpInfo() {}
~EmpInfo(){}
private:
char* m_name;
char* m_dept;
char* m_position;
long m_salary;
public:
void SetName(char* name) { m_name=name; }
void SetDept( char* dept) { m_dept = dept; }
void SetPosition( char* position ) { m_position = position; }
void SetSalary( long salary ) { m_salary = salary; }
void PrintInfo();
};
//clase derivada
class OffshoreEmpInfo : public EmpInfo {
public
//constructor y destructor
OffShoreEmpInfo() {}
~OffshoreEmpInfo() {}
private:
char* m_country;
public:
void SetCountry( char* country) { m_country = country; }
void PrintInfo();
};
void EmpInfo::PrintInfo()
{
cout << "Nombre: " << m_name << "\n";
cout <<"Departamento: " << m_dept << "\n";
cout <<"Puesto: " << m_position << "\n";
cout << "Sueldo: " << m_salary << "\n";
}
void OffshoreEmpInfo::PrintInfo()
{
EmpInfo::PrintInfo();
cout << "País: " << m_country << "\n";
}
int main()
{
//Declaración de un objeto de la clase
EmpInfo* empInfo1 = new OffshoreEmpInfo;
OffshoreEmpInfo* empInfo2 = new OffshoreEmpInfo;
//relleno del objeto con datos
empInfo1.SetName( "Gabriel Lozano" );
empInfo1.SetDept( "Entrenamientos" );
empInfo1.SetPosicion("Vocalista");
empInfo1.SetSalary(240000);
empInfo1.PrintInfo();
//relleno del objeto con datos
empInfo2.SetName( "Alvaro Tovar" );
empInfo2.SetDept( "Relaciones humanas" );
empInfo2.SetPosicion("Entrevistador");
empInfo2.SetSalary(1800000);
empInfo2.SetCountry( "Colombia" );
empInfo2.PrintInfo();
return 0;
}
La siguiente es la declaración de la clase OffShoreEmpInfo:
//clase derivada
class OffshoreEmpInfo : public EmpInfo {
public
//constructor y destructor
OffShoreEmpInfo() {}
~OffshoreEmpInfo() {}
private:
char* m_country;
public:
void SetCountry( char* country) { m_country = country; }
void PrintInfo();
};
Advierta que la cabecera de la declaración de una clase derivada contiene los nombres de ambas clases: la clase derivada y la clase base. El nombre de la clase derivada se separa del nombre de la clase base por dos elementos: dos puntos y un especificador de acceso.
Las clases derivadas pueden reemplazar o redefinir, funciones de miembro que heredan de sus clases bases. En el código anterior se redefinio la funcion PrintInfo().
El polimorfismo es un concepto clave de la programación orientada a objetos. El polimorfismo proporciona una forma de dar un nimbre a una acción que es realizada por objetos similares, implementando cada objeto la acción de una manera adecuada al objeto en concreto.
Para la implementación de polimorfismo en C++ se utiliza un tipo especial de función denominado función virtual. Una función virtual es el mecanismo por el que las clases derivadas pueden redefinir funciones de las clases base. Para crear una función virtual en un programa en C++ puede declarar la función utilizando la palabra clave virtual, como en la secuencia siguiente:
virtual void Display();
En el siguiente código se demuestra la utilización de funciones virtuales de miembro. Se declara una clase base llamada BaseClass y una función derivada, DerivedClass, cada una de las cuales define una versión diferente de una función de miembro llamada Display. La función BaseClass::Display es una función de miembro virtual y DerivedClass::Display es una función que redefine BaseClass::Display.
#include <iostream.h>
class BaseClass
{
//miembros de la clase base
public:
virtual void Display() { cout << 100 << "\n"; }
};
class DerivedClass: public BaseClass
{
//miembros de la clase derivada
public:
void Display() { cout << 200 << "\n"; }
};
void Print( BaseClass* bc)
{
bc->Display();
}
int main()
{
BaseClass* pMyBaseClass = new BaseClass;
DerivedClass* pMyDerivedClass = new DerivedClass;Print(pMyBaseClass);
Print(pMyDerivedClass);return 0;
}
En la función main del programa anterior, se instancian un objeto de una clase bae y un objeto de una clase derivada. La función main después llama a la funcioón Print.
int main()
{
BaseClass* pMyBaseClass = new BaseClass;
DerivedClass* pMyDerivedClass = new DerivedClass;Print(pMyBaseClass);
Print(pMyDerivedClass);return 0;
}
Como resultado, la función Print llama a la función de miembro BaseClass::Display y a la función de miembro DerivedClass::Display. Advierta, sin embargo, quela funciónPrint no llama a estas dos funciones utilizando dos punteros diferentes. En su lugar, utiliza el mismo puntero, concretamente bc, que,comopuede ver examinando la cabecera de la función Print, a continuación, es un puntero a BaseClass.
void Print( BaseClass* bc)
{
bc->Display();
}
Realize una agenda en donde se registre la información de contacto tanto de personas como de empresas. La información a almacenar es la siguiente:
1. Apellidos de la persona.
2. Nombre completo de la persona.
3. Dirección de la persona.
4. Telefono de la persona.
Esta información debe estar disponible tanto para personas naturales como para organizaciones. Para organizaciones se debe sumar el nombre de la empresa y la ciudad en donde esta se encuentra y el sitio web si lo hay, aparte de la información que ya se tiene que corresponde a lainformación de contacto de el gerente. En resumen, para las compañias se requiere la siguiente información aparte:
5. Nombre de la empresa.
6. Ciudad en donde se haya la empresa.
7. Dirección en internet.
Todos los registros se deben almacenar ordenados alfabeticamente utilizando el apellido y luego el nombre. Se debe poder: ver registros, adicionar registros, eliminar registros, modificar los registros y ver el contenido de un registro. Además no debe permitir el ingreso de un registro con apellidos y nombres que ya existian en la agenda. De nuevo se debe utilizar la arquitectura MVC. Con esto separamos el modelo de la vista y del controlador y podríamos, por ejemplo, en un futuro utilizar una base de datos como mecanismo de persistencia para los registros( aclaro, no en el taller).