Escolar Documentos
Profissional Documentos
Cultura Documentos
No Estticos
Mtodos ou variveis de instncia
Construtores
Funes membro especiais cujo nome o prprio nome da classe Responsveis pela inicializao dos novos objetos criados No possuem valores de retorno
No pode ser mtodo do tipo const No podem ser do tipo static
Construtores Especiais
Construtor Padro
Construtor que no recebe nenhum parmetro denominado construtor default Caso no se programe nenhum construtor, o compilador gera um construtor default Caso se programe algum construtor, o compilador deixa de fornecer o construtor default
Construtores Especiais
Construtor de Cpia
Seja o exemplo
Pilha p1(100); p1.push(10); p1.push(20); Pilha p2 = p1; p1.pop(); p1.push(30); cout << "Topo de p2" << p2.pop();
Construtores Especiais
Construtor de Cpia
O problema que o construtor de cpia gerado automaticamente faz cpia superficial (bitwise)
Cdigo do construtor de cpia Pilha::Pilha(const Pilha &pOriginal): MAX_PILHA(pOriginal.MAX_PILHA), tamanho(pOriginal.tamanho) { dados = new int[MAX_PILHA]; for (int i = 0; i < tamanho; ++i) dados[i] = pOriginal.dados[i]; }
Destrutores
Funo membro especial cujo nome o nome da classe precedido por ~ Responsveis pela liberao de memria dos objetos alocados No possuem valores de retorno No pode ser mtodo do tipo const No podem ser do tipo static No podem ser sobrecarregados, no recebem parmetros Um destrutor default fornecido pelo compilador
Problema
No definido operador =
Operador de atribuio
Implementao
Pilha & Pilha::operator=(const Pilha &pOriginal) { if (this != &pOriginal) { delete [] dados; dados = new int[pOriginal.MAX_PILHA]; tamanho = pOriginal.tamanho; for (int i = 0; i < tamanho; ++i) dados[i] = pOriginal.dados[i]; } return *this; }
Herana de Classes
Herana de Classes
Tipos de Herana
Herana Simples Subclasse herda de uma nica superclasse Herana Mltipla Subclasse herda caractersticas de duas ou mais superclasses
Sintaxe Geral
class SubClasse: [modificador] SuperClasse1, [modificador] SuperClasse2, ... [modificador] SuperClassen { ... };
Herana Simples
Hierarquia de classes para Bovinos
Animal
class Animal { public: Animal(int q): quant(q) {}; ~Animal() {}; Modificador private: int quant; de Acesso }; class Bovino: public Animal { public: Bovino(int q, char *r) : Animal(q), raca(r) {}; ~Bovino() {}; private: char raca[31]; };
Bovino
Leiteiro
Determinar como os nveis de visibilidade public e protected sero vistos pelas subclasses
Modificador de Acesso public public public private private private Acesso resultante public protected No acessvel private private No acessvel
Polimorfismo
Poligono area();
Triangulo area();
Retangulo area();
Hexagono area();
Polimorfismo em C++
Mtodos Virtuais
class Poligono { virtual float area() {...} }; class Retangulo: public Poligono { float area() {...} }; class Triangulo : public Poligono { float area() {...} };
Polimorfismo em C++
Referncia para o tipo Poligono pode assumir a forma de Poligono, Triangulo, Retangulo e Hexagono
main() { Poligono *p; P = new Poligono(); p->area(); P = new Triangulo(); P->area(); }
Facilidade de expanso
Caso se deseje trabalhar com uma nova classe chamada Quadrado, este trecho de cdigo no ser alterado em nada.
// Erro // OK // Erro // OK
Herana Mltipla
Veiculo
Terrestre
Aquatico
Anfibio
O mesmo nome de mtodo ou varivel de instncia existe em mais de uma das superclasses. Qual deles herdar?
Aquatico mover()
Veiculo
Aquatico
Anfibio
Ao se usar polimorfismo paramtrico pode ser impossvel definir qual tipo de mtodo ser invocado com base na classe que foi criada atravs de herana mltipla void f(Aquatico x) { x.mover(); } void f(Terrestre x) { x.mover(); } main() { Anfibio sapo('T'); f(sapo); // Qual f() chamar? }
Classes Amigas
Seja a classe Empregado
E m p re g a d o
n o m e : stri n g sa l a ri o : d o u b l e g e tS a l a ri o () se tS a l a ri o () g e tNo m e () se tNo m e ( )
Para pensar
Todos as classes podem alterar o salrio de um Empregado No h um mecanismo para controlar as classes que podem acessar um mtodo pblico Aspecto indesejado para a classe empregado
Classes Amigas
Uso de uma classe amiga
E m pregado
n o m e : s trin g
DRH
re vis a S a la r io s ()
s a la rio : d o u b le g e tS a la rio ( ) g e tN o m e () s e tN o m e ()
Classes Amigas
class DRH; // Implementada mais a frente class Empregado { public: double getSalario(); string getNome(); void setNome(string umNome); private: string nome; double salario; friend class DRH; }
Classes Amigas
class DRH { public: void revisaSalarios(Empregado &emp);
Classes Amigas
Problemas dessa abordagem
A classe DRH agora acessa todos os membros de Empregado, sejam eles pblicos, protegidos ou privados No h como garantir para DRH o acesso apenas ao membro salario Caso apenas o mtodo revisasalarios necessite acessar o membro salario, pode-se usar uma abordagem com mtodo amigo
Mtodos Amigos
Uso de um mtodo amigo
Empregado DRH
revisaSalarios() nome : string salario : double
<<friend>>
Apenas o mtodo revisaSalarios da Classe DRH acessa todos os dados internos de Empregado
Mtodos Amigos
class DRH { public: void revisaSalarios(Empregado &emp); } class Empregado { public: double getSalario(); string getNome(); void setNome(string umNome); private: string nome; double salario; }
Funes Amigas
Uso de uma funo amiga
Empregado
nome : string salario : double revisaSalarios()
<<friend>>
Funes Amigas
class Empregado { public: double getSalario(); string getNome(); void setNome(string umNome); private: string nome; double salario; }
Caso se tenham classes que embora no se relacionem via herana, esto fortemente acopladas e a performance est sendo afetada pela comunicao entre as classes, pode-se definir uma classe como amiga da outra para minimizar o overhead das chamadas de mtodo entre as classes preciso registrar que esta abordagem viola o princpio do encapsulamento e s deve ser usada de forma controlada.
Em geral, quando se faz sobrecarga de operadores preciso trabalhar com funes friend para garantir a sintaxe habitual do operador Veremos esse tpico em detalhes no estudo de sobrecarga de operadores
Problema 05
Implemente as classes Vetor e Matriz onde:
Vetor possui os mtodos getValue(x) e setValue(x) para acessar e setar valores Matriz possui os mtodos getValue(x, y) e setValue(x,y) nos mesmos moldes Os dados so privados
Problema 06
Implemente a funo friend de multiplicao de matriz por vetor
Sobrecarga de funes
Pode-se sobrecarregar uma funo com declaraes mltiplas do mesmo nome de funo no mesmo escopo. As declaraes diferem no nmero e no tipo dos argumentos recebidos.
void imprima(int i) { cout << "Um int " << i << endl; } void imprima(double d) { cout << "Um double " << d << endl; }
Sobrecarga de funes
As funes sobrecarregadas podem ser funes membro (ou mtodos) de uma classe
class Documento { public: void imprima(char *titulo); void imprime(char *titulo, int copias); void imprime(int copias); }
Define um tipo inteiro que guarda valores numa determinada faixa Contruo desejvel para um cliente da classe RangeInt seria
RangeInt x, y, z; x = 100; y = 150; z = x + y;
Caso no se tenha sobrecarga de operadores pode-se trabalhar com mtodos para definir as operaes
Sobrecarregando operadores
Formas de Sobrecarga
Operadores como mtodos da classe Operadores como funes friend da classe Operadores como funes gerais
Sintaxe geral
<tipo> operator <smbolo>(<parmetros>);
Observaes
Dependendo do tipo de implementao da sobrecarga (mtodo ou funo) e do tipo do operador (unrio ou binrio) o total de parmetros ser alterado
Sobrecarregando operadores
Sobrecarga do operador + de RangeInt
class RangeInt { public: ... RangeInt(int val = 0); RangeInt operator+(RangeInt &opDireita) { if ( valor + opDireita.valor > high || valor + opDireita.valor < low) { // Gera exceo } return RangeInt(valor+opDireita.valor); } ... };
Sobrecarregando operadores
Contruo vlida
RangeInt x, y, z; x = 100; y = 150; z = x+y; z = x.operator+(y)
Sobrecarregando operadores
Sobrecarga com funo friend
class RangeInt { ... friend RangeInt operator+(const RangeInt &, const RangeInt &) }; inline RangeInt operator+(const RangeInt &esq, const RangeInt &dir) { RangeInt novo; if (esq.valor + dir.valor > esq.high || esq.valor + dir.valor < esq.low) { // Gera exceo } else { novo.valor = esq.valor + dir.valor; } return novo; }
Sobrecarga de Operadores
class MyInt { public: MyInt(int x) : value(x) {} int getValue() const { return value;} MyInt operator+(const MyInt &op) { return MyInt(value + op.value); } MyInt operator+(int op) { return MyInt(op + value); } friend ostream &operator<<(ostream& o, MyInt& p) { o << p.getValue(); return o; } private: int value; };
Os operadores de C++ a seguir no podem ser sobrecarregados: . .* :: ?: No se pode mudar a precedncia, o nmero de operandos ou agrupamento dos operadores padro de C++
Como diferenciar as verses pr e ps incremento (decremento) se o nmero de argumentos no varia? ++x x.operator++(); x++ x.operator++(); ???? Ps-incremento (decremento) recebe um parmetro fictcio do tipo int ++x x.operator++(); x++ x.operator++(int nao_usado);
Permite o compilador fazer converses de tipos incorretos no primeiro argumento Garante a sintaxe correta (usual) do operador Permite usar classes j definidas (ou tipos base) como primeiro operando do operador
Qualquer operador que requer um lvalue melhor implementado como uma funo membro
Permite operaes em cascata: a = b = c; cout << "x = " << x << endl;
Operador binrio + cria um novo objeto a = b + c; Para evitar que o resultado seja usado como um lvalue retorna-se uma constante b + c = a; // Invlido
Converses de Tipos
C++ realiza converses automticas de tipos Usando construtor de converso de tipo class A { class B { public: public: A() {} B(const A &objA) {} }; }; void f(B b) {} main() { A a; f(a); }
Converses de Tipos
Usando operador de converso class C { int i; public: C(int ii) { i = ii; } }; class D { int x; public: D(int xx) { x = xx; } operator C() const { return C(x); } };
Converses de Tipos
Inibindo converses automticas class A { public: A() {} }; class B { public: explicit B(const A &objA) {} }
Classes Template
Implementao na linguagem C++ do conceito de genericidade Conhecidas tambm como classes genricas ou geradores de classes Sintaxe de definio
template <class TipoTemp_1,, class TipoTemp_n> class NomeClasse { // Definio da classe template };
Uso de VOrdenado
main() { VOrdenado<int> vInt(10); Vordenado<string> vStr(3); for (int i = 0; i < 10; ++i) vInt[i] = 10-i; cout << vInt << endl; vInt.ordena(); cout << vInt << endl; vStr[0] = "Zebra"; vStr[1] = "Ana"; vStr[2] = "Carla"; cout << vStr << endl; vStr.ordena(); cout << vStr << endl; }
Iteradores
Funcionam como apontadores
Podem ser incrementados/decrementados Pode-se obter o seu contedo ou campo apontado Iteradores so classes criadas com o objetivo de simular apontadores H um controle maior sobre o mecanismo de funcionamento do iterador So chamados super-apontadores Independncia da classe a ser percorrida pelo iterador
No so simplesmente apontadores
Grande uso