• Olá Visitante, se gosta do forum e pretende contribuir com um donativo para auxiliar nos encargos financeiros inerentes ao alojamento desta plataforma, pode encontrar mais informações sobre os várias formas disponíveis para o fazer no seguinte tópico: leia mais... O seu contributo é importante! Obrigado.

divisão de código entre arquivos

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
O padrão ao se escrever em C++ aconselha a declaração de uma classe no cabeçalho e sua implementação em um arquivo .cpp. Isso, em primeiro lugar, é uma questão de organização e não uma restrição do compilador ou da linguagem.

Digamos que você queira fornecer uma biblioteca para programadores, mas não deseja mostrar como a fez, por que sua intenção é vendê-la.

O que fazer? Declarar a classe com seus métodos e atributos em um arquivo (header) e a implementação (o fonte propriamente dito) em outro. Você apenas forneceria os headers e a biblioteca.

Note que, se você usa uma biblioteca com direitos autorais contra copia, você só tem arquivos de biblioteca e arquivos headers, mas não possui a sua implementação.

Mas como funciona isso tudo?

Vocês que vem do C, sabem que o compilador da Borland requer protótipos de função. Caso ele encontre uma chamada a uma função f() que ele desconheça o protótipo, ocorre um erro.

Veja uma declaração de classe como se fosse um protótipo. Antes de qualquer implementação ser avaliada pelo compilador, ele procura pela respectiva declaração. Se não encontrá-la, gera um erro.

No entanto, para uma definição de classe contida na declaração da mesma (calma, tem um exemplo logo abaixo), o compilador não se irrita, e cria o seu ansiado arquivo-objeto.

Pensando assim, poderemos pensar no que pode ser feito.

Há algo de errado em colocar a implementação contida na definição (em apenas um arquivo)? De forma alguma. Uma nota para usuários Borland: para códigos de implementação (códigos que envolvem atribuição, implementação de métodos, etc) faca-os em um arquivo .cpp. Arquivos headers não são compilados. ( bcc32 –c arquivo.h : *ERROR* ) a não ser que se forneça um command-line option indicando ao compilador para que ele *não* reconheça arquivos .h como headers.

Ok, um arquivo .cpp contendo uma implementação de classe, sem declaração (analogamente, em C, isso é o mesmo que definir uma função antes da função main()). Não precisa declarar um protótipo extra.
 

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
//teste.cpp
//não tem “#include teste.h”, obviamente,
//já que a implementação e declaração estão aqui:
class teste
{
public:
void fazerAlgo( int x )
{
x ++;
};
private:
void NinguemMeVe()
{
int h;
h = 2;
};
};
//-----------------------EOF------------------------




Vamos complicar. Um belo dia você escreve uma classe que está grande ou pode facilmente ser modularizada, e você gostaria de dispor seus arquivos de forma mais organizada. Muito bem.

Poderia ser colocado no header a declaração dessa classe, como costumeiro, e dividir os .cpp em módulos.




Exemplo:



Automovel.h //contém a declaração da classe com 3 métodos:
//void inicializar(), void mudarMarcha(), void ligarMotor()
Automovel_inicializacao.cpp //define o método void inicializar()
Automovel_cambio.cpp //define o método void mudarMarcha()
Automovel_motor.cpp //define o método void ligarMotor()




Cada um desses arquivos .cpp seriam responsáveis por implementar um determinado conjunto de métodos declarados no Automovel.h. Cada fonte teria um #include “Automovel.h”

Aumentando a aposta: duas ou mais classes em um arquivo?

Por que não?

Que tal declarar três classes em um arquivo header e implementar as três classes em um arquivo .cpp? Ótimo.



//Arquivo: meuheader.h
#ifndef MEUHEADER
#define MEUHEADER
class biscoito
{
public:
void cozinhar();
};
class laranja
{
public:
void descascar();
};
class torrada
{
public:
void torrar();
};
#endif
//------------------EOF-----------------//
//Arquivo: definicoes.cpp
#include "meuheader.h"
#include <iostream>
using std::cout;
void biscoito::cozinhar()
{
cout << "cozinhando\n";
}
void laranja::descascar()
{
cout << "descascando\n";
}
void torrada::torrar()
{
cout << "torrando\n";
}
//-------------------EOF--------------------------




Desorganizado? Muito! funciona? Sim..........
 

helldanger1

GForum VIP
Entrou
Ago 1, 2007
Mensagens
29,631
Gostos Recebidos
1
Vamos colocar tudo em um só arquivo .cpp



//Arquivo: tudojunto.cpp
#ifndef MEUHEADER
#define MEUHEADER
#include <iostream>
using std::cout;
class biscoito
{
public:
void cozinhar()
{
cout << "cozinhando\n";
};
};
class laranja
{
public:
void descascar()
{
cout << "descascando\n";
};
};
class torrada
{
public:
void torrar()
{
cout << "torrando\n";
};
};
#endif
//-------------------------EOF------------------------




Quer usar essas classes aí em cima no seu código?

Faca um #include “tudojunto.cpp”

Também não é o ideal.

Faça as declarações das classes em um arquivo .H e reserve um arquivo .cpp para a implementação de cada classe.

A definição está muito grande? Divida a definição em seções, como explicado anteriormente. Isso tudo é a critério do programador (do seu chefe, se não for você mesmo), que deve ter o senso de organização bem apurado.

A maneira como se organiza a disposição das classes não muda o modo como o programa funciona, não muda seu código em si. É um critério de organização da implementação. Porém existem algumas limitações e regras impostas pelo pré-processador. Por exemplo, erros de inclusão circular podem ocorrer. Isso não acontece quando incluímos “guardas” nos headers:



#ifndef NOME_DA_DEFINICAO
#define NOME_DA_DEFINICAO

/* codigo */

#endif




Outro erro possível de aparecer é uma dependência mútua entre classes. Porém, pretendo explicar a solução para esse problema futuramente.




By:Jester
 
Topo