Programação · 15 min read · Oct 10, 2025
Aprendendo C/C++ Passo a Passo - Página 13
13. Passo a Passo C/C++ — Programação C++ - OOPs
OOP (Programação Orientada a Objetos) em C++
| | 1. Paradigma Orientado a Objetos
- Características da Linguagem Orientada a Objetos
- Objetos
- Classes
- Abstração de dados
- Encapsulamento de dados
- Herança
- Polimorfismo
- Ligação dinâmica
- Passagem de mensagens
- História do C++
- Classes e Objetos
- Funções membro definidas fora da classe
- Array de Objetos
- Objetos como Argumentos
- Retornando Objetos de funções
- Construtor
- Destrutores
- Sobrecarga de Construtores
- Dados de Classe Estáticos
- Funções Membro Estáticas
- Funções Amigas |
1. Paradigma Orientado a Objetos
A ideia básica por trás do Paradigma Orientado a Objetos é combinar em uma única unidade tanto os dados quanto as funções que operam sobre esses dados. Tal unidade é chamada de objeto.
Através desse método, não podemos acessar os dados diretamente. Os dados estão ocultos, portanto, estão seguros de alterações acidentais. Os dados e suas funções são ditos estar encapsulados em uma única entidade. O encapsulamento de dados e a ocultação de dados são termos-chave na descrição da linguagem orientada a objetos.
Um programa C++ normalmente consiste em vários objetos, que se comunicam entre si chamando as funções membro uns dos outros. A organização de um programa C++ é mostrada nesta figura.
| |
|
2. Características da Linguagem Orientada a Objetos
Aqui estão alguns dos principais elementos das linguagens orientadas a objetos.
| | - Objetos
- Classes
- Abstração de dados
- Encapsulamento de dados
- Herança
- Polimorfismo
- Ligação dinâmica
- Passagem de mensagens |
| |
Objetos
Um objeto é uma instância de uma classe. Combinando tanto dados quanto funções membro. Objetos são as entidades básicas em tempo de execução em um sistema orientado a objetos. | | |
Classes
Um modelo ou esboço que define as características de um objeto e descreve como o objeto deve parecer e se comportar. | | |
Abstração de Dados
Identificando as características distintivas de uma classe ou objeto sem ter que processar todas as informações sobre a classe ou objeto. Quando você cria uma classe — por exemplo, um conjunto de botões de navegação em uma tabela — você pode usá-la como uma única entidade em vez de acompanhar os componentes individuais e como eles interagem. | | |
Encapsulamento de Dados
Um termo de programação orientada a objetos para a capacidade de conter e ocultar informações sobre um objeto, como estruturas de dados internas e código. O encapsulamento isola a complexidade interna da operação de um objeto do resto da aplicação. Por exemplo, quando você define a propriedade Caption em um botão de comando, você não precisa saber como a string é armazenada. | | |
Herança
Um termo de programação orientada a objetos. A capacidade de uma subclasse assumir as características da classe da qual é baseada. Se as características da classe pai mudarem, a subclasse da qual é baseada herda essas características.
Para herdar as qualidades da classe base para a classe derivada. | | |
Polimorfismo
Um termo de programação orientada a objetos. A capacidade de ter métodos com o mesmo nome, mas conteúdo diferente, para classes relacionadas. O procedimento a ser usado é determinado em tempo de execução pela classe do objeto. Por exemplo, objetos relacionados podem ter ambos os métodos Draw. Um procedimento, passado tal objeto como parâmetro, pode chamar o método Draw sem precisar saber que tipo de objeto é o parâmetro. | | |
Ligação Dinâmica
Dinâmico refere-se à ligação de uma chamada de procedimento ao código a ser executado em resposta à chamada. Ligação dinâmica significa que o código associado a uma determinada chamada de procedimento não é conhecido até o momento da chamada em tempo de execução. Está associado ao polimorfismo e à herança. Uma chamada de função associada a uma referência polimórfica depende do tipo dinâmico dessa referência. | | |
Passagem de Mensagens
Um programa orientado a objetos consiste em um conjunto de objetos que se comunicam entre si. O processo de programação em uma linguagem orientada a objetos, portanto, envolve os seguintes passos básicos:
- Criar classes que definem objetos e seu comportamento.
- Criar objetos a partir das definições de classe.
- Estabelecer comunicação entre objetos. |
3. História do C++
| Ano | Linguagem | Desenvolvido por | Observações |
| 1960 | ALGOL | Comitê Internacional | Muito geral, Muito abstrato |
| 1963 | CPL | Universidade de Cambridge | Difícil de aprender, Difícil de implementar |
| 1967 | BCPL | Martin Richards | Podia lidar apenas com problemas específicos |
| 1970 | B | Ken Thompson
AT & T Bell Labs | Podia lidar apenas com problemas específicos | | 1972 | C | Dennis Ritchie
AT & T Bell Labs | Perdeu a generalidade de BCPL e B restaurada | | Início dos anos 80 | C++ | Bjarne Stroustrup
AT & T | Introduz OOPs. |
C++ é uma linguagem de programação orientada a objetos. Inicialmente chamada de ‘C com Classes’, C++ foi desenvolvida por Bjarne Stroustrup nos laboratórios Bell da AT & T em Murry Hill, Nova Jersey, EUA, no início dos anos oitenta.
Stroustrup, um admirador do Simula67 (uma linguagem OOP) e um forte defensor do C, queria combinar o melhor de ambas as linguagens e criar mais poder e elegância no C. O resultado foi C++.
C++ é uma verdadeira Linguagem Orientada a Objetos, portanto, deve ser uma coleção de classes e objetos.
4. Classes e Objetos
Uma classe é uma maneira de vincular os dados e suas funções associadas. Permite que os dados sejam ocultados, se necessário, do uso externo. Ao definir uma classe, estamos criando um novo tipo de dado abstrato que pode ser tratado como qualquer outro tipo de dado embutido. Geralmente, uma especificação de classe tem duas partes:
| | 1. Declaração da classe
- Definição da função da classe |
A declaração especifica o tipo e o escopo tanto dos dados quanto das funções membro da classe. Enquanto a definição especifica o código executável da função.
A forma geral de uma declaração de classe é:
| | class class_name
{
private:
declarações de variáveis;
declarações de funções;
public:
declarações de variáveis;
declarações de funções;
}; |
A declaração da classe é semelhante à declaração de struct. A palavra-chave class especifica que os dados e funções são privados por padrão. Enquanto a palavra-chave struct especifica que os dados e funções são públicos por padrão. As palavras-chave private e public são conhecidas como rótulos de visibilidade.
| |
|
Aqui está um exemplo de classe para implementar uma classe de funcionário.
| |
|
O seguinte é o programa completo da classe emp.
| | // Programa para aceitar e exibir informações do funcionário
#include
using namespace std;
class emp // definição da classe
{
private : // dados privados, funções
int eno;
char name[10];
float sal;
public : // dados públicos, funções
void getdata()
{ cin >> eno >> name >> sal; }
void putdata()
{ cout << eno << name << sal; }
};
int main()
{
emp e;
e.getdata();
e.putdata();
return 0;
} |
5. Funções membro definidas fora da classe
Há uma possibilidade de definir funções membro fora da classe usando o operador de resolução de escopo (::).
| | // Programa para aceitar e exibir informações do funcionário
#include
using namespace std;
class emp // definição da classe
{
private : // dados privados, funções
int eno;
char name[10];
float sal;
public : // dados públicos, funções
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. Array de Objetos
O compilador C++ também suporta array de objetos.
O exemplo abaixo ilustra a vantagem de Objetos usando arrays.
| | // Programa para aceitar e exibir informações do funcionário
#include
using namespace std;
class emp // definição da classe
{
private : // dados privados, funções
int eno;
char name[10];
float sal;
public : // dados públicos, funções
void getdata()
{ cin << eno << name << sal; }
void putdata()
{ cout >> eno >> name >> sal; }
};
int main()
{
emp e[10]; // declaração do array de objetos
for(i = 0; i <10; i++) // acessando propriedades e métodos dos objetos
e[i].getdata();
for(i = 0; i< 10; i++)
e[i].putdata();
return 0;
} |
7. Objetos como Argumentos
Passar Objetos para funções é semelhante a passar estruturas, arrays para funções. O seguinte programa demonstra como objetos são passados para funções.
| | // Programa para aceitar e exibir informações do funcionário
#include
using namespace std;
class emp // definição da classe
{
private : // dados privados, funções
int eno;
char name[10];
float sal;
public : // dados públicos, funções
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 funções
Vimos objetos sendo passados como argumentos para funções, agora discutiremos como retornar objetos de funções.
| | // Programa para aceitar e exibir informações do funcionário
#include
using namespace std;
class emp // definição da classe
{
private : // dados privados, funções
int eno;
char name[10];
float sal;
public : // dados públicos, funções
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. Construtor
O seguinte exemplo mostra duas maneiras de dar valores aos itens de dados em um objeto. Às vezes, no entanto, é conveniente se um objeto puder se inicializar quando é criado pela primeira vez, sem a necessidade de fazer uma chamada separada para uma função membro.
A inicialização automática é realizada usando uma função membro especial chamada construtor. Um construtor é uma função membro que é executada automaticamente sempre que um objeto é criado.
| | // Programa para aceitar e exibir informações do funcionário usando construtores
#include
#include
using namespace std;
class emp // definição da classe
{
private : // dados privados, funções
int eno;
char name[10];
float sal;
public : // dados públicos, funções
emp() { ; } // construtor sem argumentos
emp(int teno, char tname[10], float tsal) // construtor com 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;
} |
O programa de exemplo acima aceita valores de duas maneiras usando construtores e usando funções membro. Um objeto, sempre que foi declarado, foi automaticamente inicializado com os valores dados usando construtores. Enquanto o objeto e2 é acessível apenas por sua função membro.
Mais um exemplo para distinguir o uso do construtor.
| | // Objetos representam uma variável contador
#include
using namespace std;
class counter
{
private :
int count; // variável count
pubilc :
counter() { count = 0; } // construtor
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(); // exibir
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(); // exibir novamente
cout << “\nC2 = “ << c2.get_count();
return 0;
} |
| | Um construtor tem as seguintes características.
- Inicialização automática
- Valores de retorno não são aceitos
- Mesmo nome que a classe
- Bagunçando com o formato |
10. Destrutores
Um destrutor tem o mesmo nome que o construtor (que é o mesmo que o nome da classe) mas precedido por um til:
| | // Demonstração de um destrutor
#include
using namespace std;
class temp
{
private :
int data;
public :
temp() { data = 0; } // Construtor (mesmo nome que a classe)
~temp() { } // destrutor (mesmo nome com til)
}
int main()
{
temp t;
return 0;
} |
11. Sobrecarga de Construtores
A capacidade de ter funções com o mesmo nome, mas conteúdo diferente, para classes relacionadas. O procedimento a ser usado é determinado em tempo de execução pela classe do objeto.
| | // Demonstração de uma sobrecarga de construtor
#include
using namespace std;
class ttime
{
private :
int hh, mm, ss;
public :
ttime() {hh = 0; mm = 0; ss = 0; } // Construtor com inicialização
ttime(int h, int m, int s) // Construtor com 3 argumentos
{
hh = h; mm = m ; ss = s;
}
ttime(int h, int m) // Construtor com 2 argumentos
{
hh = h; mm = m; ss = 0;
}
ttime(int h) // Construtor com 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); // Chamando construtores
t1.get_time();
t1.put_time();
t2.put_time();
t3.put_time();
t4.put_time();
return 0;
} |
12. Dados de Classe Estáticos
Se um item de dados em uma classe é definido como estático, então apenas um tal item é criado para toda a classe, não importa quantos objetos existam. Um item de dados estático é útil quando todos os objetos da mesma classe devem compartilhar um item comum de informação. Uma variável membro definida como estática tem características semelhantes a uma variável estática normal: é visível apenas dentro da classe, mas sua duração é todo o programa.
| | // Demonstração de um dado estático
#include
using namespace std;
class temp
{
private :
static int count; // Apenas um item de dados para todos os objetos
public :
temp() { count++; } // incrementar count quando o objeto é criado
int getcount() { return count; } // retornar count
};
int main()
{
temp t1, t2, t3; // criar três objetos
cout << “\nCount is “ << t1.getcount( ); // cada objeto
cout << “\nCount is “ << t2.getcount( ); // vê o mesmo
cout << “\nCount is “ << t3.getcount( ); // valor de count
return 0;
} | | | A saída do programa acima é a seguinte: (se ainda for estático)
Count is 3
Count is 3
Count is 3
A saída do programa acima (se for automático)
Count is 1
Count is 1
Count is 1 |
13. Funções Membro Estáticas
Assim como a variável membro estática, também podemos ter funções membro estáticas. Uma função membro que é declarada estática tem as seguintes propriedades.
| | - Uma função estática pode ter acesso apenas a outros membros estáticos (funções ou variáveis) declarados na mesma classe.
- Uma função membro estática pode ser chamada usando o nome da classe (em vez de seus objetos) da seguinte forma:
class-name :: function-name;
|
| | // Programa para demonstrar função membro estática
#include
using namespace std;
class test
{
int code ;
static int count; // variável membro estática
public:
void setcode() { code = ++count; }
void showcode() { cout << “Número do objeto :” << code << endl; }
static void showcount() // função membro estática
{
cout << “Count :” << count << endl;
}
};
int test :: count;
int main()
{
test t1, t2;
t1.setcode();
t2.setcode();
test::showcount(); // acessando função estática
test t3;
t3.setcode();
test::showcount();
t1.showcode();
t2.showcode();
t3.showcode();
return 0;
} |
14. Funções Amigas
| |
|
Os membros privados não podem ser acessados de fora da classe. Ou seja, uma função não membro não pode ter acesso aos dados privados de uma classe. No entanto, pode haver uma situação em que gostaríamos que duas classes compartilhassem uma função específica. Isso é simplesmente alcançado através de funções Amigas.
| | Uma função amiga possui certas características especiais: - Não está no escopo da classe à qual foi declarada como amiga.
- Como não está no escopo da classe, não pode ser chamada usando o objeto da classe. Pode ser invocada como uma função normal sem a ajuda de nenhum objeto.
- Ao contrário das funções membro, não pode acessar os nomes dos membros diretamente e deve usar um nome de objeto e o operador de membro de ponto com cada nome de membro.
- Pode ser declarada tanto na parte pública quanto na parte privada de uma classe sem afetar seu significado.
- Geralmente, tem os objetos como argumentos. |
| | // Programa para demonstrar função 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 são os membros privados
// da classe test, mas eram acessíveis
// pela função amiga
}
int main()
{
test x;
x.setvalue();
cout << “Valor médio = “ << sum(x) << endl;
return 0;
} |
Mais um exemplo para implementar funções amigas como uma ponte entre duas classes.
O seguinte programa cria dois objetos de duas classes e uma função amiga para duas classes.
Neste exemplo, a função amiga é capaz de acessar os membros de dados de ambas as classes e calcula o maior de ambos os membros de dados da classe.
| | #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 os membros de dados de first, second podem ser
cout << “Max “<< f.a; // acessados através da função amiga max
else
cout << “Max “<< s.b;
}
int main()
{
first f(20);
second s(30);
max(f, s);
return 0;
} |
Ref: Programação Orientada a Objetos em Turbo C++: Robert Lafore
Receba novas postagens na sua caixa de entrada
Sem spam. Cancele a assinatura a qualquer momento.