Programación · 16 min read · Oct 10, 2025

Aprendiendo C/C++ Paso a Paso - Página 13

13. Paso a Paso C/C++ — Programación en C++ - OOPs

OOP (Programación Orientada a Objetos) en C++

| | 1. Paradigma Orientado a Objetos

  1. Características del Lenguaje Orientado a Objetos
  • Objetos
  • Clases
  • Abstracción de datos
  • Encapsulamiento de datos
  • Herencia
  • Polimorfismo
  • Vínculo dinámico
  • Paso de mensajes
  1. Historia de C++
  2. Clases y Objetos
  3. Funciones miembro definidas fuera de la clase
  4. Arreglo de Objetos
  5. Objetos como Argumentos
  6. Retornando Objetos de funciones
  7. Constructor
  8. Destructores
  9. Sobrecarga de Constructores
  10. Datos de Clase Estáticos
  11. Funciones Miembro Estáticas
  12. Funciones Amigas |

1. Paradigma Orientado a Objetos

La idea básica detrás del Paradigma Orientado a Objetos es combinar en una sola unidad tanto los datos como las funciones que operan sobre esos datos. Tal unidad se llama objeto.

A través de este método no podemos acceder a los datos directamente. Los datos están ocultos, por lo que están a salvo de alteraciones accidentales. Se dice que los datos y sus funciones están encapsulados en una sola entidad. El encapsulamiento de datos y el ocultamiento de datos son términos clave en la descripción del lenguaje orientado a objetos.

Un programa en C++ típicamente consiste en un número de objetos, que se comunican entre sí llamando a las funciones miembro de uno al otro. La organización de un programa en C++ se muestra en esta figura.

| | |

2. Características del Lenguaje Orientado a Objetos

Aquí hay algunos elementos principales de los lenguajes orientados a objetos.

| | - Objetos

  • Clases
  • Abstracción de datos
  • Encapsulamiento de datos
  • Herencia
  • Polimorfismo
  • Vínculo dinámico
  • Paso de mensajes |

| |
Objetos
Un objeto es una instancia de una clase. Combina tanto datos como funciones miembro. Los objetos son las entidades básicas en tiempo de ejecución en un sistema orientado a objetos. | | |
Clases
Una plantilla o plano que define las características de un objeto y describe cómo debe lucir y comportarse el objeto. | | |
Abstracción de Datos
Identificar las características distintivas de una clase u objeto sin tener que procesar toda la información sobre la clase u objeto. Cuando creas una clase — por ejemplo, un conjunto de botones de navegación de tabla — puedes usarla como una sola entidad en lugar de hacer un seguimiento de los componentes individuales y cómo interactúan. | | |
Encapsulamiento de Datos
Un término de programación orientada a objetos para la capacidad de contener y ocultar información sobre un objeto, como estructuras de datos internas y código. El encapsulamiento aísla la complejidad interna de la operación de un objeto del resto de la aplicación. Por ejemplo, cuando estableces la propiedad Caption en un botón de comando, no necesitas saber cómo se almacena la cadena. | | |
Herencia
Un término de programación orientada a objetos. La capacidad de una subclase para asumir las características de la clase de la que se basa. Si las características de la clase padre cambian, la subclase de la que se basa hereda esas características.
Para heredar las cualidades de la clase base a la clase derivada. | | |
Polimorfismo
Un término de programación orientada a objetos. La capacidad de tener métodos con el mismo nombre, pero contenido diferente, para clases relacionadas. El procedimiento a utilizar se determina en tiempo de ejecución por la clase del objeto. Por ejemplo, objetos relacionados pueden tener ambos métodos Draw. Un procedimiento, que pasa tal objeto como parámetro, puede llamar al método Draw sin necesidad de saber qué tipo de objeto es el parámetro. | | |
Vínculo Dinámico
Dinámico se refiere al enlace de una llamada a procedimiento con el código que se ejecutará en respuesta a la llamada. El vínculo dinámico significa que el código asociado con una llamada a procedimiento dada no se conoce hasta el momento de la llamada en tiempo de ejecución. Está asociado con polimorfismo y herencia. Una llamada a función asociada con una referencia polimórfica depende del tipo dinámico de esa referencia. | | |
Paso de Mensajes
Un programa orientado a objetos consiste en un conjunto de objetos que se comunican entre sí. El proceso de programación en un lenguaje orientado a objetos, por lo tanto, implica los siguientes pasos básicos:

  1. Crear clases que definan objetos y su comportamiento.
  2. Crear objetos a partir de definiciones de clase.
  3. Establecer comunicación entre objetos. |

3. Historia de C++

AñoLenguajeDesarrollado porComentarios
1960ALGOLComité InternacionalDemasiado general, demasiado abstracto
1963CPLUniversidad de CambridgeDifícil de aprender, difícil de implementar
1967BCPLMartin RichardsSolo podía tratar problemas específicos

| 1970 | B | Ken Thompson
AT & T Bell Labs | Solo podía tratar problemas específicos | | 1972 | C | Dennis Ritchie
AT & T Bell Labs | Perdió la generalidad de BCPL y B restaurada | | Principios de los 80 | C++ | Bjarne Stroustrup
AT & T | Introduce OOPs. |

C++ es un lenguaje de programación orientado a objetos. Inicialmente llamado ‘C con Clases’, C++ fue desarrollado por Bjarne Stroustrup en los laboratorios Bell de AT & T en Murry Hill, Nueva Jersey, EE. UU., a principios de los años ochenta.

Stroustrup, un admirador de Simula67 (un lenguaje OOP) y un fuerte defensor de C, quería combinar lo mejor de ambos lenguajes y crear un C más poderoso y elegante. El resultado fue C++.

C++ es un verdadero Lenguaje Orientado a Objetos, por lo que debe ser una colección de clases y objetos.

4. Clases y Objetos

Una clase es una forma de unir los datos y sus funciones asociadas. Permite que los datos estén ocultos, si es necesario, del uso externo. Al definir una clase, estamos creando un nuevo tipo de dato abstracto que puede ser tratado como cualquier otro tipo de dato incorporado. Generalmente, una especificación de clase tiene dos partes:

| | 1. Declaración de clase

  1. Definición de función de clase |

La declaración especifica el tipo y el alcance tanto de los datos como de las funciones miembro de la clase. Mientras que la definición especifica el código ejecutable de la función.

La forma general de una declaración de clase es:

| | class class_name
{
private:
declaraciones de variables;
fuciones de declaración;
public:
declaraciones de variables;
fuciones de declaración;
}; |

La declaración de clase es similar a la declaración de struct. La palabra clave class especifica que los datos y funciones son privados por defecto. Mientras que una palabra clave struct especifica que los datos y funciones son públicos por defecto. Las palabras clave private y public son conocidas como etiquetas de visibilidad.

| | |

Aquí hay un ejemplo de clase para implementar una clase de empleado.

| | |

El siguiente es el programa completo de la clase emp.

| | // Programa para aceptar y mostrar información del empleado
#include
using namespace std;
class emp                                             // definición de clase
{
private :                                     // datos privados, funciones
int eno;
char name[10];
float sal;
public :                                      // datos públicos, funciones
void getdata()
{ cin >> eno >> name >> sal;  }
void putdata()
{ cout << eno << name << sal;  }
};
int main()
{
emp e;
e.getdata();
e.putdata();
return 0;
} |

5. Funciones miembro definidas fuera de la clase

Hay una posibilidad de definir funciones miembro fuera de la clase usando el operador de resolución de ámbito (::).

| | // Programa para aceptar y mostrar información del empleado
#include
using namespace std;
class emp                                             // definición de clase
{
private :                         // datos privados, funciones
int eno;
char name[10];
float sal;
public :                                      // datos públicos, funciones
void getdata();
void putdata();
};
void emp::getdata()
{   cin >> eno >> name >> sal;  }
void emp::putdata()
{   cout << eno << name << sal; }
int main()
{
emp e;
e.getdata();
e.putdata();
return 0;
} |

6. Arreglo de Objetos

El compilador de C++ también soporta arreglos de objetos.
El siguiente ejemplo ilustra la ventaja de los Objetos usando arreglos.

| | // Programa para aceptar y mostrar información del empleado
#include
using namespace std;
class emp                                             // definición de clase
{
private :                         // datos privados, funciones
int eno;
char name[10];
float sal;
public :                                      // datos públicos, funciones
void getdata()
{ cin << eno << name << sal;  }
void putdata()
{ cout >> eno >> name >> sal;  }
};

int main()
{
emp e[10];                     // declaración de arreglo de objetos
for(i = 0; i <10; i++)        // accediendo a propiedades y métodos de objetos
e[i].getdata();
for(i = 0; i< 10; i++)
e[i].putdata();
return 0;
} |

7. Objetos como Argumentos

Pasar Objetos a funciones es similar a pasar estructuras, arreglos a funciones. El siguiente programa demuestra cómo se pasan objetos a funciones.

| | // Programa para aceptar y mostrar información del empleado
#include
using namespace std;
class emp                                             // definición de clase
{
private :                         // datos privados, funciones
int eno;
char name[10];
float sal;
public :                                      // datos públicos, funciones
void getdata()
{ cin >> eno >> name >> sal;  }
void putdata()
{ cout << eno << name << sal;  }
};
void operate(emp t);
int main()
{
emp e;
operate(e);
}
void operate(emp t)
{
t.getdata();
t.putdata();
return 0;
} |

8. Retornando Objetos de funciones

Vimos objetos siendo pasados como argumentos a funciones, ahora discutiremos cómo retornar objetos de funciones.

| | // Programa para aceptar y mostrar información del empleado
#include
using namespace std;
class emp                                             // definición de clase
{
private :                         // datos privados, funciones
int eno;
char name[10];
float sal;
public :                                      // datos públicos, funciones
void getdata()
{ cin >> eno >> name >> sal;  }
void putdata()
{ cout << eno << name << sal;  }
};
emp get();
void put(emp t);
int main()
{
emp e;
e = get();
put(e);
return 0;
}
emp get()
{
emp t;
t.getdata();
return t;
}
void put(emp t)
{
t.putdata();
} |

9. Constructor

El siguiente ejemplo muestra dos formas de dar valores a los elementos de datos en un objeto. Sin embargo, a veces es conveniente que un objeto pueda inicializarse a sí mismo cuando se crea por primera vez, sin necesidad de hacer una llamada separada a una función miembro.

La inicialización automática se lleva a cabo utilizando una función miembro especial llamada constructor. Un constructor es una función miembro que se ejecuta automáticamente cada vez que se crea un objeto.

| | // Programa para aceptar y mostrar información del empleado usando constructores
#include
#include
using namespace std;
class emp                               // definición de clase
{
private :                         // datos privados, funciones
int eno;
char name[10];
float sal;
public    :                        // datos públicos, funciones
emp() { ; }                  // constructor sin argumentos
emp(int teno, char tname[10], float tsal) // constructor con argumentos
{
eno = teno;
strcpy(name, tname);
sal = tsal;
}
void getdata()
{ cin >> eno >> name >> sal;  }
void putdata()
{ cout << eno << name << sal << endl;  }
};

int main()
{
emp e1(1001, “Magic”, 6700.45);
emp e2;
e2.getdata();
e1.putdata();
e2.putdata();
return 0;
} |

El programa de ejemplo anterior acepta valores de dos maneras utilizando constructores y utilizando funciones miembro. Un objeto, cada vez que se declara, se inicializa automáticamente con los valores dados utilizando constructores. Mientras que el objeto e2 es accesible solo a través de su función miembro.

Un ejemplo más para distinguir el uso del constructor.

| | //  Objetos representan una variable contador
#include
using namespace std;
class counter
{
private :
int count;                                 // variable count
pubilc :
counter()           { count = 0; }    // constructor
void inc_count() { count++; }    // incrementar count
int get_count()   { return count; }  // retornar count
};
int main()
{
counter c1, c2;                     // definir e inicializar
cout << “\nC1 = “ << c1.get_count();       // mostrar
cout << “\nC2 = “ << c2.get_count();
c1.inc_count();                            // incrementar c1
c2.inc_count();                            // incrementar c2
c2.inc_count();                            // incrementar c2
cout << “\nC1 = “ << c1.get_count();       // mostrar de nuevo
cout << “\nC2 = “ << c2.get_count();
return 0;
} |

| | Un constructor tiene las siguientes características.

  • Inicialización automática
  • No se aceptan valores de retorno
  • Mismo nombre que la clase
  • Desorden con el formato |

10. Destructores

Un destructor tiene el mismo nombre que el constructor (que es el mismo que el nombre de la clase) pero precedido por una tilde:

| | // Demostración de un destructor
#include
using namespace std;
class temp
{
private :
int data;
public :
temp() { data = 0;  }                    // Constructor (mismo nombre que la clase)
~temp() { }                                 // destructor (mismo nombre con tilde)
}
int main()
{
temp t;
return 0;
} |

11. Sobrecarga de Constructores

La capacidad de tener funciones con el mismo nombre, pero contenido diferente, para clases relacionadas. El procedimiento a utilizar se determina en tiempo de ejecución por la clase del objeto.

| | // Demostración de una sobrecarga de constructor
#include
using namespace std;
class ttime
{
private :
int hh, mm, ss;
public :
ttime() {hh = 0; mm = 0; ss = 0; } // Constructor con inicialización
ttime(int h, int m, int s)         // Constructor con 3 argumentos
{
hh = h; mm = m ; ss = s;
}
ttime(int h, int m)               // Constructor con 2 argumentos
{
hh = h; mm = m; ss = 0;
}
ttime(int h)                      // Constructor con 1 argumento
{
hh = h; mm = 0; ss = 0;
}
~ttime() { }
void get_time()
{
cin >> hh >> mm >> ss;
}
void put_time()
{
cout << endl << hh << “  “ << mm <<”  “ <<  ss;
}
};
int main()
{
ttime t1, t2(12, 12, 12), t3(4, 5), t4(11);       // Llamando a constructores
t1.get_time();
t1.put_time();
t2.put_time();
t3.put_time();
t4.put_time();
return 0;
} |

12. Datos de Clase Estáticos

Si un elemento de datos en una clase se define como estático, entonces solo se crea un solo elemento de este tipo para toda la clase, sin importar cuántos objetos haya. Un elemento de datos estático es útil cuando todos los objetos de la misma clase deben compartir un elemento común de información. Una variable miembro definida como estática tiene características similares a una variable estática normal: es visible solo dentro de la clase, pero su duración es la del programa completo.

| | // Demostración de un dato estático
#include
using namespace std;
class temp
{
private :
static int count;         // Solo un elemento de datos para todos los objetos
public :
temp() { count++; }       // incrementar count cuando se crea el objeto
int getcount() { return count; }        // retornar count
};
int main()
{
temp t1, t2, t3;        // crear tres objetos
cout << “\nCount es    “ << t1.getcount( ); // cada objeto
cout << “\nCount es    “ << t2.getcount( ); // ve el mismo
cout << “\nCount es    “ << t3.getcount( ); // valor de count
return 0;
} | | | La salida del programa anterior es la siguiente: (si sigue siendo estático)
Count es  3
Count es  3
Count es  3
La salida del programa anterior (si es automático)
Count es 1
Count es 1
Count es 1 |

13. Funciones Miembro Estáticas

Al igual que la variable miembro estática, también podemos tener funciones miembro estáticas. Una función miembro que se declara estática tiene las siguientes propiedades.

| | - Una función estática puede tener acceso solo a otros miembros estáticos (funciones o variables) declarados en la misma clase.

  • Una función miembro estática puede ser llamada usando el nombre de la clase (en lugar de sus objetos) de la siguiente manera:

class-name :: function-name;
|

| | // Programa para demostrar función miembro estática
#include
using namespace std;
class test
{
int code ;
static int count;   // variable miembro estática
public:
void setcode() { code = ++count; }
void showcode() { cout << “Número de objeto :” << code << endl; }
static void showcount()                     // función miembro estática
{
cout << “Count  :” << count << endl;
}
};
int test :: count;
int main()
{
test t1, t2;
t1.setcode();
t2.setcode();
test::showcount();  // accediendo a función estática
test t3;
t3.setcode();
test::showcount();
t1.showcode();
t2.showcode();
t3.showcode();
return 0;
} |

14. Funciones Amigas

| | |

Los miembros privados no pueden ser accedidos desde fuera de la clase. Es decir, una función no miembro no puede tener acceso a los datos privados de una clase. Sin embargo, podría haber una situación en la que nos gustaría que dos clases compartieran una función particular. Esto se logra simplemente a través de funciones Amigas.

| | Una función amiga posee ciertas características especiales: - No está en el ámbito de la clase a la que se ha declarado como amiga.

  • Dado que no está en el ámbito de la clase, no puede ser llamada usando el objeto de la clase. Puede ser invocada como una función normal sin la ayuda de ningún objeto.
  • A diferencia de las funciones miembro, no puede acceder a los nombres de los miembros directamente y debe usar un nombre de objeto y el operador de membresía de punto con cada nombre de miembro.
  • Puede ser declarada ya sea en la parte pública o privada de una clase sin afectar su significado.
  • Por lo general, tiene los objetos como argumentos. |

| | // Programa para demostrar función amiga
#include
using namespace std;
class test
{
int a;
int b;
public:
void setvalue() { a = 25; b = 40; }
friendly float sum(test s);             // AMIGO declarado
};
float sum(test s)
{
return float (s.a + s.b ) / 2.0;        // s.a & s.b son los miembros privados
// de la clase test pero fueron accesibles
// por la función amiga
}
int main()
{
test x;
x.setvalue();
cout << “Valor medio  = “ << sum(x) << endl;
return 0;
} |

Un ejemplo más para implementar una función amiga como un puente entre dos clases.
El siguiente programa crea dos objetos de dos clases y una función amiga a ambas clases.
En este ejemplo, la función amiga es capaz de acceder a los miembros de datos de ambas clases y calcula el mayor de ambos miembros de datos de clase.

| | #include
using namespace std;
class second;
class first
{
int a;
public:
first(int temp) { a = temp; }
friendly void max(first, second);
};
class second
{
int b;
public:
second(int temp) { b = temp; }
friendly void max(first, second);
};
void max(first f, second s)
{
if ( f.a > s.b )                     // ambos miembros de datos de first, second pueden ser
cout << “Max “<<  f.a;          // accedidos a través de la función amiga max
else
cout << “Max “<< s.b;
}
int main()
{
first f(20);
second s(30);
max(f, s);
return 0;
} |

Ref: Programación Orientada a Objetos en Turbo C++: Robert Lafore

Share: X/Twitter LinkedIn

Recibe nuevas publicaciones en tu bandeja de entrada.

No spam. Cancela la suscripción en cualquier momento.