Comparando el código en C y C++ para un nuevo tipo String sería:
struct tag_String
{
char* rep;
};
typedef tag_String* String; void InitVacio( String ); void InitCopia( String, String ); void Igualar( String, String ); void Liberar( String ); void InitCadena( String, const char*); int Length( String ); String SumarCadena( String, const char*); String SumarString( String, String); void Mostrar( String ); // No equivalente // Definición de las funciones void main( )
{
String uno = malloc( sizeof(tag_String) );
String dos = malloc( sizeof(tag_String) );
String tres = malloc( sizeof(tag_String) );
InitCadena( uno, "Hola Mundo" );
InitCopia( dos, uno );
InitVacio( tres );
Igualar( tres, SumarString(uno, SumarCadena(dos," cierto? ") )); Mostrar( tres ); } |
class String
{
public:
String( ); // Constructor sin argumentos
String( const String& ); // Constructor por copia
String& operator=( const String& ); // asignación
~String( ); // Destructor
// ... Otras operaciones del tipo
String( const char* value );
int length( ) const;
String& operator+ (const char* );
String& operator+ (String& );
friend String& operator<<( ostream&, String);
private:
char* rep; // Implementación del tipo.
};
// ... Definición de los métodos
void main( )
{
String uno = "Hola Mundo";
String dos = uno;
String tres;
tres = uno + dos + " cierto? "; cout << tres; } |
Un Tipo definido por el usuario utiliza los siguientes mecanismos de C++
... num= Length( tres ); ... |
... num = tres.length( ); ... |
int Length( String s )
{
return strlen(s->rep);
}
|
int String::length( )
{
return ::strlen(rep);
// Equivalente a return ::strlen(this->rep);
}
|
class Habitacion
{
public:
void AgregarPaciente( Paciente* );
Paciente* SacarPaciente( const char* nombre );
bool EstaPaciente( const char* nombre );
private:
int camas;
Set<Paciente*> pacientes;
};
class Hospital
{
public:
void IngresarPaciente( const char* nombre, const char* enfermedad, const char* numISS );
void DarAltaPaciente( const char* nombre );
Habitacion* BuscarHabitacion( const char* enfermedad );
private:
Set<Paciente> pacientes;
Set<Habitacion> habitaciones;
};
|
float Medico::CalcularPago( )
{
float valor=0;
Servicio* serv;
valor = numHoras*valorHora;
while( servicios.nextElement( ) )
{
serv = (Servicio*) servicios.get( );
valor += serv->getValor( );
}
}
|
void Hospital::Pagar( Medico& med )
{
pagosPendientes.add( med, med.CalcularPago( ) );
med.BorrarCuenta( );
}
|
class Medico
{
public:
//...
virtual float CalcularPago( );
}
class MedicoResidente : public Medico
{
public:
//...
virtual float CalcularPago( );
}
float MedicoResidente::CalcularPago( )
{
float valor=0;
valor = Medico::CalcularPago( );
valor += sueldoMensual;
return valor;
}
|
void Ventana::pintar( )
{
Grafico* g;
elems.first( );
while( elems.nextElement( ) )
{
g = elems.get( );
g->pintar( );
}
}
|
|
|
Este algoritmo se considera genérico, independiente del tipo de subclases de Gráfico que se modelen. En este caso se tiene un conjunto polimorfo (elems), una variable polimorfa (g) y un mensaje polimorfo (pintar) que se interpreta según sea el tipo exacto de g.
class Application
{
public:
//...
virtual void InitWindow( ) =0;
Application( )
{
mainWindow = InitWindow( );
mainWindow->run( );
}
private:
Window* mainWindow;
};
class Window
{
public:
// ...
virtual void run( )
{
// ... Implementacion ...
}
};
|
namespace Modulo1; class A
{
//... declaración de Modulo1::A
}
namespace Modulo2; class A
{
//... declaración de Modulo2::A
}
void main( )
{
Modulo1::A obj1;
Modulo1::A obj2;
// ...
}
|
Otro concepto importante en términos de modularidad es el acoplamiento
débil entre los módulos. Supongamos un módulo de interfaz
que debe reflejar el estado de un modelo del mundo. Se desearía
que el modelo del mundo no dependa en ninguna medida del módulo
de interfaz, aunque también se desea que los posibles cambios y
errores puedan mostrarse al usuario final. Una forma de lograr esta cohesión
débil es por medio del mecanismo de excepciones. Un ejemplo de su
uso puede ser:
class Hostpital
{
public:
// ...
void IngresarPaciente( const char* nombre, const char*, const char* ) throws SinCupoException
{
if( NumCamasDisponibles( ) == 0 )
throw new SinCupoException( String( "no hay cama para " ) + nombre );
else
// Otros casos de excepcion y caso por defecto...
}
};
class Window
{
public:
// ...
virtual void run( )
{
// ... Otros eventos
try
{
hospital.IngresarPaciente( "Pedro Perez", "hepatitis", "6523773" );
}
catch( SinCupoException e )
{
MessageBox( this, "No hay cupo para el paciente... Intente ingreso de urgencia" );
}
}
};
|