C++
INF1761 - Computação Gráfica
Orientação por Objetos
• Dados são modelados não apenas pela sua representação,
mas principalmente pelo seu comportamento
• Objetos são um TAD: representação interna + conjunto de
operações
• Variáveis da aplicação são objetos
• Classes são os tipos dos objetos
• Funções dos objetos são chamadas métodos
Classes em C++
typedef struct {
double xc, yc;
double raio;
} Circulo;
C
double area( Circulo e )
{ return 3.14159 * e.raio * e.raio; }
int interior( Circulo e, double x, double y)
{ … }
X
C++
struct Circulo{
double xc, yc;
double raio;
double area() { return 3.14159 * raio * raio; }
int interior(double x, double y) { … }
};
Objetos em C++
Circulo c;
c.x = 3.2;
c.y = 4.5;
c.raio = 6.5;
printf(“%d”, area( c ));
if (interior( c, 9.5, 2 )) …
C++
C
Circulo c;
c.x = 3.2;
c.y = 4.5;
c.raio = 6.5;
printf(“%d”, c.area());
if (c.interior( 9.5, 2 )) …
Encapsulamento
Declarações equivalentes
class: default é private
struct: default é public
class Classe {
int c, b;
public:
int a, d;
void set_c( int val ) { c = val; }
};
struct Classe {
private:
int c, b;
public:
int a, d;
void set_c( int val ) { c = val; }
};
Classe obj;
obj.a = 1;
obj.c = 0;
obj.set_c( 0 );
// ok
// erro - campo c é privado
// agora sim
Construtores e Destrutores
Métodos chamados implicitamente quando o objeto é criado e quando é destruído.
class Classe{
public:
Classe() { printf(“construtor\n”); }
~Classe() { printf(“destrutor\n”); }
};
void f()
Execução de f
{
Classe p1, p2; // p1 e p2 criados
printf( “funcao f\n” );
// p1 e p2 destruídos
}
construtor
construtor
funcao f
destrutor
destrutor
Construtores com parâmetros
Construtores podem ter parâmetros (destrutores não!).
Além disso, uma classe pode ter mais de um construtor,
desde que eles recebam parâmetros diferentes.
class Circulo{
double xc, yc;
double raio;
public:
Circulo( double x, double y, double r)
{ xc=x; yc=y; raio=r;}
…
};
Circulo c1( 3.2, 4.5, 9.0 ); // obriga a inicialização
Circulo c2; // erro, não tem construtor sem parâmetros
c1.xc = 4; // erro, campo xc é privado
Alocação dinâmica
class Circulo{
…
public:
Circulo();
Circulo( double x, double y, double r);
~Circulo();
};
Circulo *c1, *c2;
c1 = new Circulo; // cria um objeto da classe Circulo,
// alocando memória e chamando o
// construtor Circulo()
c2 = new Circulo( 3.2, 4.5, 9.0 ); // cria outro,
// agora com o outro construtor
…
delete c2; // destroi o objeto apontado por c2:
// chama o destrutor e desaloca memória
delete c1; // idem
Herança
Herda da classe Circulo (classe base)
class CirculoColorido : public Circulo {
int cor;
public:
CirculoColorido( double x, double y, double r, int c)
: Circulo( x, y, r ) { cor = c; }
void troca_cor( int c ) { cor = c; }
};
Inicializa a classe base antes de entrar no construtor
CirculoColorido c( 1.0, 3.4, 3.2, VERDE );
c.troca_cor( AZUL );
double a = c.area(); // ok, CirculoColorido tem tudo de Circulo
Representação dos objetos
Circulo
Circulo*
double xc
double yc
double raio
Representação da classe Circulo
CirculoColorido
CirculoColorido*
double xc
double yc
double raio
Representação da classe Circulo
int cor
Declarado em CirculoColorido
Conversão de objetos
int intersecta( Circulo *c1, Circulo *c2 );
Circulo *c1, *c2;
c1 = new Circulo(3, 4, 2);
c2 = new Circulo(3.5, 3.3, 1 );
if (intersecta(c1, c2)) …
CirculoColorido *c3;
c3 = new CirculoColorido( 2.5, 1, 3 );
if (intersecta(c1, c3)) …
Polimorfismo
class A {
virtual void nome() { printf(“classe A\n”); }
};
class B : public A {
virtual void nome() { printf(“classe B\n”); }
};
A *pa;
// ponteiros para objetos da classe A
A* obj_a = new A; // cria objeto da classe A
B* obj_b = new B; // cria objeto da classe B
pa = obj_a;
pa->nome();
// pa aponta para um objeto da classe A
// chama o metodo <nome> de A
pa = obj_b;
pa->nome();
// pa aponta para um objeto da classe B
// chama o metodo <nome> de B!!!
Abstraindo as implementações
dos objetos
Que métodos um objeto
da cena precisa ter para
permitir a implementação
desta função?
rtColor trace ( rtRay ray, int depth)
{
determine a interseção mais próxima com um objeto
if (intercepta objeto)
{
calcule a normal no ponto de interseção
return ( shade ( object, ray, intersection, normal, depth);
}
return BACKGROUND;
}
class Objeto3D {
public:
virtual double intersecta( Raio r )
= 0;
virtual Vetor3D normal( Vetor3D ponto ) = 0;
};
Implementando a função trace
Objeto3D* objetos[MAX_OBJETOS];
int n_objetos;
rtColor trace ( rtRay ray, int depth)
{
determine a interseção mais próxima com um objeto
...
Cor trace( Raio ray, int depth )
{
int mais_proximo;
double dist = -1;
for (int i=0; i<n_objetos; i++)
{
double d = objetos[i]->intersecta(ray);
if (d > 0 && (dist==-1 || d < dist))
{
dist = d;
mais_proximo = i;
}
}
...
Implementando a função trace
...
if (dist > 0)
{
Vetor3D ponto_de_inter = ray.ponto( dist );
Vetor3D normal = objetos[mais_proximo]->normal( ponto_de_inter);
return shade(objetos[mais_proximo], ray, ponto, normal, depth );
}
else
{
return BACKGROUND;
}
}
...
if (intercepta objeto)
{
calcule a normal no ponto de interseção
return ( shade ( object, ray, intersection, normal, depth);
}
return BACKGROUND;
}
Referência de C++
The C++ Programming Language
3a Edição
B. Stroustrup
Addison-Wesley, 1997
Download

cpp - PUC-Rio