Apostila C - C++
170 pág.

Apostila C - C++


DisciplinaIntrodução à Tecnologia da Computação26 materiais155 seguidores
Pré-visualização50 páginas
deste 
ponteiro, um erro fatal será gerado. 
Para evitar que este erro aconteça, implementamos o construtor de cópia para os objetos da 
classe Pessoa: 
Pessoa(Pessoa const & aP); 
Este construtor aloca um espaço de memória para armazenar os seus dados e depois copia os 
valores contidos do objeto passado como argumento. Note que esta função não copia o endereço 
contido em Nome, mas sim o valor apontado por este ponteiro. Evitando assim o problema descrito 
acima. Este construtor de cópia é muito importante, geralmente utilizado na conversão de outros 
Curso de Linguagem Computacional C/C++
 
________________________________________________________________________________________________ 
Sistemas Industriais Inteligentes \u2013 DAS \u2013 CTC \u2013 UFSC 126
objetos para este tipo ou na atribuição de objetos. Reimplemente este operador sempre que a sua 
classe contiver ponteiros com alocação dinâmica como atributos. 
16.5 Chamadas a Funções 
O objeto C1 da classe Cliente usa a função GetData() membro da classe Cliente, 
na instrução: 
C1.GetData(); 
O compilador sempre procurará primeiro pela função na classe que define o objeto (no caso, 
Cliente). Se o compilador não encontrar esta função então ele irá procurar nas classes-bases da 
classe do objeto. Se ele encontrar em uma classe-base, o compilador executará a função encontrada 
senão ocorrerá um erro. 
Podemos criar funções-membro de uma classe derivada que tenham o mesmo nome de 
funções-membro da classe-base. Isto faz com que a sintaxe da chamada a elas, por meio de um 
objeto, seja a mesma, independentemente de tratar-se de um objeto da classe-base ou da classe 
derivada. 
A função GetData() está definida com o mesmo protótipo tanto na classe-derivada 
quanto na classe-base, então qual das versões da função será utilizada pelo compilador? A regra é a 
seguinte: se duas funções de mesmo nome existem, uma na classe-base e outra na classe derivada, a 
função da classe derivada será executada se for chamada por meio de um objeto da classe 
derivada.Se um objeto da classe base é criado, usará sempre funções da própria classe-base pois não 
conhece nada sobre a classe derivada. 
Para que uma função da classe derivada, com mesmo nome de uma função da classe-base, 
possa acessar a que está na classe-base, é necessário o uso do operador de resolução de escopo 
(::): Pessoa::GetData(); 
Esta instrução executa a função GetData() da classe-base dentro da definição desta 
função na classe-derivada. Sem o uso do operador de resolução de escopo, o compilador executará a 
função GetData() da classe-derivada e o resultado será uma seqüência infinita de chamadas 
recursivas. O operador de resolução de escopo permite que se especifique exatamente qual é a 
classe da função que queremos executar. 
C2.GetData(); 
C1.Pessoa::GetData(); 
A diferença das instruções acima é que para o primeiro objeto, estaremos utilizando a versão 
da funçao GetData() definida na classe derivada e para o segundo objeto estaremos utilizando a 
versão da função definida na classe-base. A distinção entre as duas chamadas é feita pelo operador 
de resolução de escopo (::). 
16.6 Herança Pública e Privada 
Declaramos a classe derivada Cliente especificando a palavra public: 
class Cliente : public Pessoa 
A declaração public indica que os membros públicos da classe-base serão membros públicos 
da classe derivada e os membros protected da classe base serão também membros protected da 
classe derivada. Os membros públicos da classe-base podem ser acessados por um objeto da classe 
derivada. 
Curso de Linguagem Computacional C/C++
 
________________________________________________________________________________________________ 
Sistemas Industriais Inteligentes \u2013 DAS \u2013 CTC \u2013 UFSC 127
A declaração private pode ser usada no lugar de public e indica que tanto os membros 
públicos quanto os protegidos da classe-base serão membros privados da classe derivada. Estes 
membros são acessíveis aos membros da classe derivada, mas não aos seus objetos. Portanto, um 
objeto da classe derivada não terá acesso a nenhum membro da classe-base. 
Os membros privados da classe-base serão sempre inacessíveis fora da classe-base. 
Nenhuma classe derivada pode acessar um membro privado de uma classe base. 
Geralmente, a derivação privada é raramente usada. Mas há momentos em que a derivação 
privada é desejável. Por exemplo, imagine que você tenha uma função da classe-base que trabalha 
perfeitamente com objetos da classe base, mas gera resultados errados quando usado com objetos da 
classe derivada. A derivação privada neste caso é uma solução bem elegante. 
16.7 Conversões de Tipos entre Classe-Base e Derivada 
Visto que Cliente é um tipo de Pessoa, faz sentido pensar em converter um objeto da classe 
Cliente num objeto da classe Pessoa. C++ permite a conversão implícita de um objeto da 
classe derivada num objeto da classe-base. Por exemplo: 
Pessoa P3 = C1; // C1 é um objeto da classe Cliente 
Todos os membros da classe-base P3 recebem os valores dos membros correspondentes do 
objeto C1 da classe derivada. Aqui, o construtor de cópia da classe Pessoa evitará que um erro 
ocorra devido a um ponteiro presente na classe. Este construtor é utilizado para converter o objeto 
da classe derivada em um objeto da classe base sem que ambos objetos contenham o mesmo 
endereço no ponteiro e venham a causar um erro de acesso à memória. 
Entretanto a atribuição inversa não é válida, não podemos atribuir um objeto da classe-base 
a um objeto da classe derivada. 
Sobrecarregamos os operadores << associados a objetos da classe ostream, para facilitar a 
apresentação dos dados dos objetos de ambas as classes na tela. Perceba que na implementação da 
sobrecarga do operador << para o objeto da classe ostream e um objeto da classe Cliente, que 
utilizamos uma conversão na instrução abaixo: 
OS << Pessoa(C); 
Esta conversão converte temporariamente o objeto C da classe Cliente para um objeto da 
classe Pessoa. Isto causará a chamada do operador << definido para a classe Pessoa, 
imprimindo na tela os dados da classe Pessoa presentes no objeto da classe Cliente. Esta 
instrução opera como se estivéssemos chamando uma função da classe-base utilizando o operador 
de resolução de escopo. Aqui não utilizamos o operador, mas convertemos o objeto da classe 
derivada, para um objeto da classe base antes de chamarmos a função, o que tem o mesmo 
resultado. 
16.8 Níveis de Herança 
Uma classe por ser derivada de outra classe , que , por sua vez é também uma classe 
derivada. 
class X {}; 
class Y : public X {}; 
class Z : public Y {}; 
Neste exemplo, Y é derivada de X, e Z é derivada de Y. Este processo pode ser estendido 
para qualquer número de níveis, K pode ser derivada de Z, e assim por diante. 
Curso de Linguagem Computacional C/C++
 
________________________________________________________________________________________________ 
Sistemas Industriais Inteligentes \u2013 DAS \u2013 CTC \u2013 UFSC 128
16.9 Herança Múltipla 
Uma classe pode herdar as características de mais de uma classe. Este processo é chamado 
de herança múltipla. A construção de hierarquias de herança múltipla envolve mais complexidade 
do que as hierarquias de herança simples. Esta complexidade diz respeito ao desenho da construção 
das classes e não à sintaxe de uso. A sintaxe de múltiplas heranças é similar àquela de uma única 
herança. Eis um exemplo que representa os imóveis à venda de uma imobiliária : 
// Heranca Multipla 
#include <iostream> 
#include <cstdio> 
#include <iomanip> 
#include <string> 
using namespace std; 
class Cadastro 
{ 
private: 
char nome[30], fone[20]; 
public: 
Cadastro() { nome[0] = fone[0] = '\0'; } 
Cadastro(char n[], char f[]) 
{ 
strcpy(nome, n); 
strcpy(fone, f); 
} 
void GetData() 
{ 
cout << &quot;\n\tNome: &quot;; 
cin.getline(nome, 30); 
cout << &quot;\tFone: &quot;; 
cin.getline(fone, 20); 
} 
void PutData() 
{ 
cout << &quot;\n\tNome: &quot; << nome; 
cout