HIERARQUIA DE CLASSES
HIERARQUIA DE CLASSES
HERANC¸ A SIMPLES
• heran¸ca ´e uma t´ecnica para construir novas classes, chamadas de classes derivadas, a partir das j´a existentes, ditas classes base • heran¸ca permite o re´uso do comportamento de uma classe
• a classe derivada herda todas as caracter´ısticas de sua classe base e pode adicionar novas caracter´ısticas
• heran¸ca permite construir hierarquia de classes
HIERARQUIA DE CLASSES
DEFINIC¸ ˜AO UMA CLASSE BASE
class Time {
int hours, minutes, seconds; public:
Time(int hr, int min, int sec){
hours = hr; minutes = min; seconds = sec; }
void display(){
cout << hours << ’:’ << minutes << ’:’ << seconds; }
};
c++/rsb 3
HIERARQUIA DE CLASSES
DEFININDO CLASSE DERIVADA
enum timezone { gmt, est, cst, mst, pst };
char *TZ[] = {"GMT","EST","CST","MST","PST"}; class TimeZone : public Time {
|
timezone zone; +--- default ´e private public:
TimeZone(int hr, int min, int sec, timezone zn)
: Time(hr,min,sec){zone=zn;} timezone getZone( ) {return zone;}
HIERARQUIA DE CLASSES
USANDO BASE E DERIVADA
CONSTRUTORAS DE CLASSE DERIVADA
CONSTRUTORAS DE CLASSE DERIVADA
• Quando um objeto de classe derivada ´e declarado, a fun¸c˜ao
construtora da base ´e executada e, em seguida, executa-se a fun¸c˜ao construtora da derivada
• A lista de parˆametros da construtora da derivada deve conter os parˆametros da construtora da base
• A chamada da construtora da base deve ser indicada explicitamente como abaixo
class TimeZone : public Time{ ...
TimeZone(int hr, int min, int sec, timezone zn)
: Time(hr, min, sec) { ... }; ...
}
c++/rsb 7
CONSTRUTORAS DE CLASSE DERIVADA
CONSTRUTORAS DE CLASSE DERIVADA ...
• A lista de argumentos da construtora da classe base deve aparecer na declara¸c˜ao da construtora da derivada
• A chamada `a construtora da classe base deve estar associada a declara¸c˜ao da fun¸c˜ao e n˜ao do prot´otipo
class TimeZone : public Time{ ...
TimeZone(int hr, int min, int sec, timezone zn); ...
}
TimeZone::TimeZone(int hr,int min,int sec,timezone zn)
:Time(hr,min,sec){ ...
CONSTRUTORAS DE CLASSE DERIVADA
CONSTRUTORA SEM PAR ˆAMETROS
• Se n˜ao houver chamada expl´ıcita de construtora, a construtora sem parˆametros ´e chamada
class A { int x; public:
A( ):x(100) { }
int getX( ){return x;} };
class B: public A { int y;
public:
B(){ y = 1000; }
int gety( ) {return y;} };
int main(){ B b;
printf("x= %d y= %d\n", b.getX(), b.gety()); }
Sa´ıda: 100 1000
c++/rsb 9
CONSTRUTORAS DE CLASSE DERIVADA
CONSTRUTORA PRIVADA E SUBCLASSES
CONSTRUTORAS DE CLASSE DERIVADA
PONTEIROS E CLASSES DERIVADAS OU BASE
• Um apontador para uma classe base pode apontar para um objeto de uma classe dela derivada
• O tipo com o qual o ponteiro ´e declarado ´e o seu tipo est´atico e o tipo do objeto apontado ´e o seu tipo dinˆamico
• Os componentes n˜ao-virtuais da classe declarada para o ponteiro continuam acess´ıveis atrav´es dele, mesmo quando anulados
(redefinidos) int main(){
DispTime dt(21, 42, 12, pst);
Time *tp = &dt; TimeZone *zp = &dt; DispTime *dp = &dt; tp->display(); zp->display(); dp->display();
return 0; }
SAIDA: 9:42:12 9:42:12 PST 9:42:12 pm PST
c++/rsb 11
CONSTRUTORAS DE CLASSE DERIVADA
REFERˆENCIAS A CLASSE BASE E DERIVADA
• Uma referˆencia a uma classe base pode ser iniciada com um objeto de classe dela derivada
• O tipo com o qual a referˆencia ´e declarada ´e o seu tipo est´atico e o tipo do objeto referido ´e o seu tipo dinˆamico
• Os componentes n˜ao-virtuais da classe declarada para a referˆencia continuam acess´ıveis atrav´es dela, mesmo quando anulados
(redefinidos) int main(){
DispTime dt(21, 42, 12, pst);
Time& tp = dt; TimeZone& zp = dt; DispTime& dp = dt; tp.display(); zp.display(); dp.display();
return 0;
FUNC¸ ˜OES VIRTUAIS
Fun¸c˜oes Virtuais
FUNC¸ ˜OES VIRTUAIS
• Fun¸c˜ao virtual ´e aquela definida numa classe base e que espera ser anulada por uma fun¸c˜ao em uma classe derivada como o mesmo nome e tipos de parˆametros
• Um apontador para uma classe base pode apontar para um objeto de uma classe dela derivada
• Os componentes virtuais acess´ıveis da classe s˜ao os componentes do objeto apontado, independentemente do tipo do apontador que
chama o componente
Fun¸c˜oes Virtuais
CLASSE COM FUNC¸ ˜OES VIRTUAIS
class Time {
int hours, minutes, seconds; public:
Time(int hr, int min, int sec){
hours = hr; minutes = min;seconds = sec; }
virtual void display(){
cout << hours << ’:’ << minutes << ’:’ << seconds; }
};
c++/rsb 15
Fun¸c˜oes Virtuais
CLASSE COM FUNC¸ ˜OES VIRTUAIS...
enum timezone { gmt, est, cst, mst, pst };
char *TZ[] = {"GMT","EST","CST","MST","PST"}; class TimeZone : public Time {
timezone zone; public:
TimeZone(int hr,int min,int sec,timezone zn) :Time(hr,min,sec){ zone = zn;
}
virtual void display() { // virtual opcional
Time::display(); cout << ’ ’ << TZ [zone]; }
Fun¸c˜oes Virtuais
CLASSE COM FUNC¸ ˜OES VIRTUAIS...
inline int adjust(int hour) {
return hour > 12 ? hour - 12 :(hour == 0 ? 12 : hour); }
inline char makeampm(int hour) { return hour < 12 ? ’a’ : ’p’; }
c++/rsb 17
Fun¸c˜oes Virtuais
CLASSE COM FUNC¸ ˜OES VIRTUAIS...
class DispTime : public TimeZone { char ampm;
public:
DispTime(int hr,int min,int sec,timezone zn)
Fun¸c˜oes Virtuais
REFERˆENCIA A UMA FUNC¸ ˜AO VIRTUAL
Fun¸c˜oes Virtuais
CLASSES ABSTRATAS
• Uma classe abstrata ´e uma que especifica uma ou mais fun¸c˜oes virtuais puras
• Fun¸c˜ao virtual pura n˜ao tem corpo
Exemplo: virtual void display( ) = 0;
• Fun¸c˜oes virtuais puras devem ser definidas por alguma subclasse da classe abstrata
• Subclasses que n˜ao definem as fun¸c˜oes virtuais nulas herdadas tamb´em s˜ao abstratas
• Pode haver hierarquia de classe abstratas
Fun¸c˜oes Virtuais
FUNC¸ ˜AO VIRTUAL PURA
• Time ´e uma classe abstrata
class Time {
int hours, minutes, seconds; public:
Time(int hr, int min, int sec) {
hours = hr; minutes = min; seconds = sec; }
void displayTime() {
cout << hours << ’:’ << minutes << ’:’ << seconds; }
virtual void display() = 0;
};
enum timezone { gmt, est, cst, mst, pst };
char *TZ[] = { "GMT", "EST", "CST","MST", "PST" };
c++/rsb 21
Fun¸c˜oes Virtuais
FUNC¸ ˜AO VIRTUAL PURA...
class TimeZone : public Time { timezone zone;
public:
Fun¸c˜oes Virtuais
FUNC¸ ˜AO VIRTUAL PURA...
Fun¸c˜ao Destruidora
FUNC¸ ˜OES DESTRUIDORAS DA BASE E DERIVADA
• Quando um objeto de uma classe derivada sai do escopo de
execu¸c˜ao, a fun¸c˜ao destruidora da classe derivada ´e executada e, em seguida, a fun¸c˜ao destruidora para a classe base ´e executada
• No caso de delete p, onde p ´e ponteiro para a classe base, a
destruidora da base ser´a executada, mesmo se p aponta para objeto da classe derivada
• Quando a fun¸c˜ao destruidora for virtual, todas as destruidoras abaixo dela na hierarquia s˜ao virtuais, e o compilador chama a destruidora correta
• Fun¸c˜oes construtoras n˜ao podem ser virtuais
c++/rsb 25
Fun¸c˜ao Destruidora
CHAMANDO DESTRUIDORA DA BASE
class Company { char *name; public:
Company(char *s){
name = new char[strlen(s+1)]; strcpy(name, s);
}
~Company( ) {
cout << "Destruidor C"; delete name; }
Fun¸c˜ao Destruidora
CHAMANDO DESTRUIDORA DA BASE ...
class Division : public Company { char *manager;
public:
Fun¸c˜ao Destruidora
CHAMANDO DESTRUIDORA DA BASE...
int main(){
Company *companies[3];
companies[0] = new Company("Casa de Software SJT");
companies[1] = new Division("Pequenos Sistemas", "Carolina"); companies[2] = new Division("Grandes Sistemas", "Patricia"); ... // processa os objetos da companhia
for (int i = 0; i < 3; i++) {
Fun¸c˜ao Destruidora DESTRUIDORA VIRTUAL class Company { char *name; public: Company(char *s){
name = new char[strlen(s+1)]; strcpy(name, s); }
virtual ~Company( ) {
cout << "Destruidor C";delete name; }
void printOrgName() { cout << name; } };
c++/rsb 29
Fun¸c˜ao Destruidora
DESTRUIDORA VIRTUAL
class Division : public Company { char *manager;
public:
Division(char *s, char *mgr) : Company(s){
Fun¸c˜ao Destruidora
DESTRUIDORA VIRTUAL
int main(){
Company *companies[3];
companies[0] = new Company("Casa de Software SJT");
companies[1] = new Division("Pequenos Sistemas", "Carolina"); companies[2] = new Division("Grandes Sistemas", "Patricia"); ...
ESCOPO DOS MEMBROS DE CLASSE
ESCOPO DOS MEMBROS DE CLASSE
• membros p´ublicos (public) de uma classe s˜ao acess´ıveis a todo o programa
• membros privados (private) de uma classe somente s˜ao acess´ıveis a membros fun¸c˜oes da classe
• membros privados da classe base n˜ao s˜ao acess´ıveis `a classe derivada • membros protegidos(protected) da classe base s˜ao acess´ıveis a
membros de classes derivadas (filhas, netas, ...), mas privados para o resto do programa
c++/rsb 33
ESCOPO DOS MEMBROS DE CLASSE
ESCOPO DOS MEMBROS DA CLASSE BASE
• class B : private A { ... } ou class B : A { ... }:
os membros p´ublicos e protegidos de uma classe base s˜ao membros privados da classe derivada de classe base private
• class B : public A { ... }:
os membros p´ublicos e protegidos de uma classe base s˜ao,
respectivamente, membros p´ublicos e protegidos da classe derivada de classe base public
• class B : protected A { ... }:
ESCOPO DOS MEMBROS DE CLASSE
ESCOPO DOS MEMBROS DE CLASSE...
class X {
int priv;// private por default protected: int prot; public: int publ; void m(); } void X::m() { priv := 1; // OK prot := 2; // OK publ := 3; // OK }
class Y: public X { void g(); }
c++/rsb 35
ESCOPO DOS MEMBROS DE CLASSE
ESCOPO DOS MEMBROS DE CLASSE...
void Y::g( ) {
priv := 1; // ERRO: priv ´e privado
prot := 2; // OK: prot ´e protected e g ´e membro de // classe derivada
publ := 3; // OK: publ ´e publico }
void f(Y* p) {
p-> priv := 1; // ERRO:priv ´e privado
p-> prot := 2; // ERRO:prot ´e protected, mas f n~ao // ´e friend ou membro de X ou Y
HERANC¸ A M ´ULTIPLA
Heran¸ca M´ultipla
HERANC¸ A M ´ULTIPLA
• Heran¸ca m´ultipla ´e a capacidade de uma classe derivada ter mais de uma classe base
• Uma derivada de duas bases:
class FileStamp:public Time, public Date{ ...
};
• A construtora de uma classe derivada de bases m´ultiplas deve
especificar os argumentos para as fun¸c˜oes construtoras de todas as classes base
Heran¸ca M´ultipla
USANDO HERANC¸ A M ´ULTIPLA
class Time {
int hours, minutes, seconds; public:
Time(int h, int m, int s) {
hours = h; minutes = m; seconds = s; }
virtual void display() {
cout << hours << ’:’ << minutes << ’:’ << seconds; }
};
c++/rsb 39
Heran¸ca M´ultipla
USANDO HERANC¸ A M ´ULTIPLA
class Date {
int month, day, year; public:
Date(int m, int d, int y){
month = m; day = d; year = y; }
virtual void display(){
cout << month << ’/’ <<day << ’/’ <<year; }
Heran¸ca M´ultipla
USANDO HERANC¸ A M ´ULTIPLA...
class FileStamp1 : public Time, public Date { char filename[15];
public:
Heran¸ca M´ultipla
USANDO HERANC¸ A M ´ULTIPLA...
int main(){
FileStamp1 fs("DADOS",4,6,90,13,32,27); fs.display();
}
Heran¸ca M´ultipla
AMBIGUIDADES COM HERANC¸ A M ´ULTIPLA
class FileStamp2 : public Time, public Date { char filename[15];
public:
Classes Base Virtuais
CLASSES BASE VIRTUAIS
• Com heran¸ca m´ultipla, uma classe derivada pode ter mais de uma ocorrˆencia de uma das bases
• Observe a ambig¨uidade de referˆencia a x em D: class A { ... int x; ... }
class B : public A { ... x ... } class C : public A { ... x ... }
class D : public B, public C { ... x(?) ... }
• Solu¸c˜ao: classe base A deve ser declarada virtual: class A { ... int x; ... }
class B : public virtual A { ... x ... } class C : public virtual A { ... x ... } class D : public B, public C { ... x ... }
• Classe base declarada virtual implica que todas as suas ocorrˆencias compartilham uma ´unica ocorrˆencia real
c++/rsb 45
Classes Base Virtuais
BASE VIRTUAL I
class A {public: int x;};
class B: public virtual A { }; class C: public virtual A { }; class D: public B, public C { public:
D() {x = 1000;}; // OK };
int main(int argc, char *argv[]){ D d;
printf("x = %d\n", d.x); }