Anda di halaman 1dari 35

Aula 09

Construtores
Herana
CONSTRUTORES
Construtores
Um Construtor um tipo especial de funo pertencente a
uma classe. Ele automaticamente invocado quando um
objeto dessa classe declarado.
Construtores so usados tipicamente para inicializar
atributos da classe para valores default ou providos pelo
usurio.
Ou, tambm, para fazer o setup prvio antes de usar uma
classe (ex.: abrir um arquivo ou banco de dados).
Construtores tm regras especficas de nomenclatura:
Devem sempre ter o mesmo nome da clase (at as letras maisculas
e minsculas;
No devem retornar parmetro algum (nem mesmo void)
#ifndef DATA_H
#define DATA_H

#include <iostream>

Construtores using namespace std;

class Data{
public:
int ano;
int mes;
int dia;

Construtores so apenas para Data(){


inicializao, e no podem ser ano = 0;
mes = 1;
chamados explicitamente; dia = 1;
Mais de um construtor pode ser }
definido, em um processo de Construtores
sobrecarga; Data(int a, int m, int d){
ano = a;
mes = m;
dia = d;
}

void print() {
cout << ano << "/" << mes << "/" << dia<<endl;
}
};

#endif
Construtores Construtor padro

Data(){
ano = 0;
mes = 1;
dia = 1;
}

Data(int a, int m, int d){ Nota: recomendvel escrever


construtores que fazem pouco,
ano = a; ou nenhum trabalho pesado.
O objetivo do construtor
mes = m; inicializar o objeto para que ele
dia = d; seja utilizado em outros trechos de
cdigo.
}
#include <iostream>
#include "data.h"

Default Constructors using namespace std;


(Contrutores Padro)
int main()
{
Data dt1;

cout << "A data 1: ";


dt1.print();
Um Construtor que no recebe
parmetro (ou que tem Data dt2(2017,05,04);
parmetros pr-definidos)
chamado de default Constructor cout << endl;
ou Constructor Padro. cout << "May the fourth be with you!"<< endl;
dt2.print();
O default Constructor chamado cout << endl;
sempre que o usurio no
prov valores de inicializao. Data dt3 = Data(2020,07,02);

cout << "A data 3: ";


dt3.print();
cout << endl;

system("pause");
return 0;
}
A sada do programa
Lista de inicializao
As duas formas de inicializao de variveis no construtor so equivalentes;
A segunda mais recomendada, principalmente quando seus atributos so objetos
com construtores padro.

Data(int a, int m, int d){


ano = a; Data(int a, int m, int d):
mes = m; ano(a),mes(m),dia(d){
dia = d; }
}
// Construtor [1]
Construtores com valores Data(){
Padro
ano = 0;
mes = 1;
dia = 1;
}
Podemos definir construtores
com valores padro;
Esses construtores vo se // Construtor [2]
comportar de forma semelhante
aos construtores padro Data(int a, int m, int d):
quando invocados sem ano(a),mes(m),dia(d){
argumentos;
E vo ser construtores comuns
}
quando invocados com
argumentos;
// Construtor [3]
Data(int a = 0, int m = 1, int d = 1):
ano(a),mes(m),dia(d){
}
Construtores

Caso sua classe no tenha um mtodo Construtor, o C++


vai criar um construtor default (que no faz nada);
Porm, altamente recomendado que toda classe tenha
um Construtor (mesmo que seja o default);
Assim, podemos assegurar que os valores dos atributos
desta classe no sejam lixo.
HERANA
Herana
Uma relao de herana entre dois objetos define uma
relao do tipo um entre estes.
Por exemplo, podemos definir uma classe chamada fruta e dizer que
banana e maa so fruta.
Assim, atributos e funcionalidades de uma determinada
classe podem ser usados pelas classes que a herdam.
Podemos dizer por exemplo que fruta tem um nome (string), cor
(string) e peso (float). Assim, toda maa e banana tambm tero estes
atributos.
As classes que herdam podem assim, utilizar e at aprimorar
caractersticas e funcionalidades da classe herdada.
Herana

Em C++, a classe da qual se herda chamada de classe pai,


classe base ou superclasse (parent class, base class,
or superclass).
J a classe que herda chamada de classe filho, clase
derivada ou subclasse (child class, derived class,
or subclass).
#ifndef ANIMAL_H
#define ANIMAL_H
Exemplo: classe base
class Animal{
public:
double altura;
double peso;

Animal(){
altura = 0;
Define dois atributos... peso = 0;
E dois mtodos construtores. }

Animal(double a, double p):


altura(a), peso(p){
}
};

#endif
class Gato: public Animal{
public:
string nome;
Exemplo: classe derivada
Gato(){
peso = 0;
altura = 0;
nome = "";
}

Gato(double p, double a, string n){


peso = p;
Tem, tambm, os atributos
altura = a;
herdados da classe base
nome = n;
}

void miar(void){
cout << nome << ": Miau!" << endl;
cout << nome << " pesa " << peso << " kg ";
cout << "e mede " << altura << "cm" << endl;
}
};
O output
#include <iostream>
#include "animal.h"
#include "gato.h"

using namespace std;

int main() {

Gato g1(15.0,30.0,"Garfield");

g1.miar();

return 0;
}
Ordem de construo
Quando criamos um objeto de uma classe herdeira, este
composto de duas ou mais partes:
Parte(s) referente(s) a(s) classe(s) herdada(s) (ou classe base)
Uma parte referente a classe herdeira (ela prpria)
Assim, quando inicializamos um objeto de uma classe
herdeira (chamamos seu construtor), executado o
construtor padro classe mais acima na rvore de
herana (que no herdeira de nenhuma outra classe), que
constri esta parte da classe herdeira.
Em seguida, executa-se o construtor da classe logo abaixo
na arvore de herana.
E assim por diante at alcanar a classe que efetivamente
queramos construir.
Ordem de construo
#include <iostream> class C : public B
using namespace std; {
public:
class A
{
C()
public: {
A() cout<<"C \n";
{ }
cout<<"A \n"; };
}
};
class D : public C
class B : public A
{
{ public:
public: D()
B() {
{ cout<<"D \n";
cout<<"B \n"; }
}
};
};
Ordem de construo
#include <locale.h>
#include "inheritance_2.cpp" //Nome do arquivo onde foram criadas as classes A, B, C e D

using namespace std;

int main()
{
setlocale (LC_ALL,"Portuguese");

cout<<"Construindo A: \n";
A oA;

cout<<"Construindo B: \n";
B oB;

cout<<"Construindo C: \n";
C oC;

cout<<"Construindo D: \n";
D oD;

return 0;
}
Cdigo do slide anterior
Objetos A, B, C e D
Selecionando o Construtor
No podermos inicializar diretamente os atributos da
classe filho herdados da classe pai na lista de
inicializao do Contrutor da classe filho.
Podemos contornar este problema de forma simples.
Trabalhando com herana, podemos especificar qual
construtor da classe pai queremos usar para criar um
objeto da classe filho.
Para fazermos isso, basta chamarmos o construtor (da classe pai) que
queremos utilizar na lista de inicializao da classe filho (que herda).
Cdigo para a criao das classes Pessoa e Estudante

#include <iostream>
#include <string>

class Pessoa
{
public:
std::string m_nome;
int m_idade;

Pessoa(std::string nome = "", int idade = 0)


: m_nome(nome), m_idade(idade)
{
}

std::string get_nome() const {return m_nome;} //Declarao e corpo da funo em uma linha
para economizar espao
int get_idade() const
{
return m_idade;
}
};
Continuao do cdigo...
Repare que Estudante herda publicamente Pessoa

class Estudante : public Pessoa //Estudante herda publicamente Pessoa


{
public:
std::string m_matricula;
std::string m_periodo;

Estudante(std::string nome = "", int idade = 0, std::string matricula = "", std::string periodo = "")
//Chama o construtor de pessoa para setar o valor de m_nome e m_idade
: Pessoa(nome, idade), m_matricula(matricula), m_periodo(periodo)
{
}

std::string get_matricula() const {return m_matricula;}


std::string get_periodo() const {return m_periodo;}
};

Chamamos o Construtor da
classe Pessoa e o inicializamos
com os valores nome e idade!!!
Funo main() para criarmos objetos das classe criadas

#include <locale.h>
#include "inheritance_1.cpp" //Nome do arquivo onde foram criadas as classes Pessoa e Estudante

using namespace std;

int main()
{
setlocale (LC_ALL,"Portuguese");

//Chamando o construtor de Pessoa


Pessoa p1("Joo",25);

cout<<"O nome da pessoa : "<<p1.get_nome()<<" e a idade : "<<p1.get_idade()<<" anos.\n\n\n";

//Chamnado o construtor de Estudante


Estudante e1("Fbio", 18, "17/1234567", "2017/1");

cout<<O nome do estudante : "<<e1.get_nome()<<"; Idade: "<<e1.get_idade()<<"\n";


cout<<"Matrcula: "<<e1.get_matricula()<<"; Perodo: "<<e1.get_periodo()<<endl;

return 0;
}
Cdigo do slide anterior
Objetos do tipo Pessoa e Estudante
Exerccio 1
Refaa a classe Fracao da aula anterior, dessa vez usando construtores. A sua classe deve receber o
valor do numerador e do denominador na construo e tambm conter um mtodo para somar fraes
corretamente. Faa uma funo main que utiliza essa classe.

Exerccio 2
Crie a classe Publicacao, que deve ter como atributos o nome e o ano de uma determinada
publicao. Faa tambm a classe Livro, que deve herdar de Publicacao, e ter os atributos gnero e
autor. Tambm crie mtodos que imprimem esses dados na tela e uma funo main que utilize essas
classes.
Exerccio 3
Crie a classe Poligono, que deve receber, na construo, o nmero de lados e o comprimento de cada
lado de um polgono regular. A rea de um polgono regular dada por:
2
=
180
4tan( )

onde o comprimento do lado do polgono e o nmero total de lados. Mtodos para clculo do
permetro e rea tambm so necessrios.
Exerccio 4
Faa a classe Prisma, que herda de Poligono, e tem um mtodo que calcula o volume do prisma. O
construtor dessa classe deve receber todas as informaes necessrias para calcular a rea e
permetro da base (que o polgono), bem como o volume, ou seja, ele deve receber todas as
informaes do construtor do Poligono, mais a altura do prisma. Lembrando que o volume de um
prisma a rea da base (o polgono), vezes a altura.
Gabarito Exerccio 1
Refaa a classe Fracao da aula anterior, dessa vez usando construtores. A sua classe deve receber o
valor do numerador e do denominador na construo e tambm conter um mtodo para somar fraes
corretamente. Faa uma funo main que utiliza essa classe.
#include <iostream>
#include "fracao.h"

using namespace std; main.cpp


int main() {
// Declarar variaveis
Fracao fa(4,3);
Fracao fb(2,4), fc;

// Realizar multiplicacao
fc = fa.multiplicar(fb);
cout << "A multiplicacao e: " << fc.m_numerador << "/" << fc.m_denominador << endl;

// Realizar soma
fc = fa.somar(fb);
cout << "A soma e: " << fc.m_numerador << "/" << fc.m_denominador << endl;

return 0;
}
Gabarito Exerccio 1
Refaa a classe Fracao da aula anterior, dessa vez usando construtores. A sua classe deve receber o
valor do numerador e do denominador na construo e tambm conter um mtodo para somar fraes
corretamente. Faa uma funo main que utiliza essa classe.

#ifndef FRACAO_H
#define FRACAO_H
fracao.h
class Fracao{
public:
int m_numerador;
int m_denominador;

Fracao();
Fracao(int num, int den);

Fracao multiplicar(Fracao f1);


Fracao somar(Fracao frac);
};

#endif
#include "fracao.h"

fracao.cpp // Construtor padrao


Fracao::Fracao(): m_numerador(0), m_denominador(1){

Gabarito Exerccio 1 }

// Construtor
Fracao::Fracao(int num, int den){
m_numerador = num;
m_denominador = den;
}

Refaa a classe Fracao da aula Fracao Fracao::multiplicar(Fracao f1){


anterior, dessa vez usando Fracao resultado;
construtores. A sua classe deve // Multiplicacao: numerador vezes numerador e
// denominador vezes denominador
receber o valor do numerador e do resultado.m_numerador = f1.m_numerador*m_numerador;
denominador na construo e resultado.m_denominador = f1.m_denominador*m_denominador;
tambm conter um mtodo para return resultado;

somar fraes corretamente. Faa }

uma funo main que utiliza essa Fracao Fracao::somar(Fracao frac){


classe. int num, den;
// Na soma o numerador do resultado e:
// n = n1*d2 + n2*d1
num = m_numerador*frac.m_denominador + m_denominador*frac.m_numerador;
// E o denomindor:
// d = d1*d2
den = m_denominador*frac.m_denominador;
Fracao res(num,den);
return res;
}
Gabarito Exerccio 2
Crie a classe Publicacao, que deve ter como atributos o nome e o ano de uma determinada
publicao. Faa tambm a classe Livro, que deve herdar de Publicacao, e ter os atributos gnero e
autor. Tambm crie mtodos que imprimem esses dados na tela e uma funo main que utilize essas
classes.
publicacao.h publicacao.cpp
#ifndef PUCLICACAO_H #include<string>
#define PUCLICACAO_H #include<iostream>
#include "publicacao.h"
#include <string>
Publicacao::Publicacao(){
using namespace std; nome = "";
ano = 0;
class Publicacao{ }
public:
string nome; Publicacao::Publicacao(string name, unsigned int year){
unsigned int ano; nome = name;
ano = year;
Publicacao(); }
Publicacao(string name, unsigned int
year); void Publicacao::print(){
cout << nome << " " << ano;
void print(void); }
};

#endif
Gabarito Exerccio 2
Crie a classe Publicacao, que deve ter como atributos o nome e o ano de uma determinada
publicao. Faa tambm a classe Livro, que deve herdar de Publicacao, e ter os atributos gnero e
autor. Tambm crie mtodos que imprimem esses dados na tela e uma funo main que utilize essas
classes. livro.cpp
livro.h #include<string>
#include<iostream>
#ifndef LIVRO_H
#include "publicacao.h"
#define LIVRO_H
#include "livro.h"

#include<string>
Livro::Livro(){
#include "publicacao.h"
genero = "";
autor = "";
using namespace std;
}

class Livro: public Publicacao{


Livro::Livro(string name, unsigned int year, string gen,
public: string aut){
string genero; nome = name;
string autor; ano = year;
genero = gen;
Livro(); autor = aut;
Livro(string name, unsigned int ano, }
string genero, string autor);

void Livro::print(){
void print(void);
Publicacao::print();
};
cout << " " << genero << " " << autor;
}
#endif
Gabarito Exerccio 2 #include <iostream>
#include "publicacao.h"
#include "livro.h"

int main() {

Publicacao p1("Dicionario Aurelio",1999);


Crie a classe Publicacao, que deve
ter como atributos o nome e o ano p1.print();
de uma determinada publicao. cout << endl;
Faa tambm a classe Livro, que
deve herdar de Publicacao, e ter os Livro l1("Harry Potter",1997,"Aventura","J.K.Rowling");

atributos gnero e autor. Tambm


l1.print();
crie mtodos que imprimem esses
cout << endl;
dados na tela e uma funo main
que utilize essas classes. return 0;
}
Gabarito Exerccio 3
Crie a classe Poligono, que deve receber, na construo, o nmero de lados e o comprimento de cada
lado do polgono. Mtodos para clculo do permetro e rea tambm so necessrios.

polygon.h polygon.cpp
#ifndef POLYGON_H #include<cmath>
#define POLYGON_H #include "polygon.h"

namespace constants{ using namespace std;


const double PI = 3.14159265;
} Polygon::Polygon(){
num_sizes = 3;
class Polygon{ len_size = 1.0;
public: }

int num_sizes; Polygon::Polygon(int ns, double ls){


double len_size; num_sizes = ns;
len_size = ls;
Polygon(); }
Polygon(int ns, double ls);
double Polygon::calc_area(){
double calc_area(void); return
double calc_perim(void); pow(len_size,2)*num_sizes/(4*tan(constants::PI/num_sizes));
}
};
#endif double Polygon::calc_perim(){
return num_sizes*len_size;
}
Gabarito Exerccio 3
Crie a classe Poligono, que deve receber, na construo, o nmero de lados e o comprimento de cada
lado do polgono. Mtodos para clculo do permetro e rea tambm so necessrios.

#include <iostream>
#include "polygon.h"

using namespace std;

int main() {

Polygon p1(4,1.0);

cout << "O perimetro de p1 e: " << p1.calc_perim() << endl;


cout << "A area de p1 e: " << p1.calc_area() << endl;

return 0;
}
Exerccio 4
Faa a classe Prisma, que herda de Poligono, e tem um mtodo que calcula o volume do prisma. O
construtor dessa classe deve receber todas as informaes necessrias para calcular a rea e
permetro da base (que o polgono), bem como o volume, ou seja, ele deve receber todas as
informaes do construtor do Poligono, mais a altura do prisma. Lembrando que o volume de um
prisma a rea da base (o polgono), vezes a altura.
prism.h prism.cpp
#ifndef PRISM_H #include "prism.h"
#define PRISM_H
using namespace std;
#include "polygon.h"
Prism::Prism(){
class Prism: public Polygon{
height = 1.0;
public:
}
double height;
Prism::Prism(int ns, double ls, double h):
Prism(); Polygon(ns,ls), height(h){
Prism(int ns, double ls,double h); }

double calc_vol(void); double Prism::calc_vol(){


}; return height*calc_area();
}
#endif