terça-feira, novembro 14, 2006

Exercício

Estude Streams Readers e Writers nos slides nos doc do java.
Extenda a dir.java para executar iterativamente, acrescentando o comando del.
Use e estude Console.java

quinta-feira, outubro 26, 2006

Compilar em Java

Para compilar em Java, digite primeiramente no prompt de comando, "path=%path&;c:\...caminho da pasta q esta o\jdk1.5.0_06\bin"

Uma vez feito isso, agora utilize o comando "javac NomedoArquivo.java", depois para executa-lo digite "java NomedoArquivo"

Escrevi isso só em caso de alguém esquecer.

[]'s

Exercício

Estude a Classe String, a Classe stringBuffer, a Classe Excepcion e as classes de invólucros do tipo primitivo(Integer, etc).

quinta-feira, outubro 19, 2006

Aula do dia 19 de outubro

Vou deixar o link pra puxar aqui, porque estou com preguiça de formatar em html.

Aula dia 19 de outubro Prog 3

Abraço!

quinta-feira, outubro 05, 2006

Gabarito

Aqui esta o Gabarito da List para download, hospedado no site do CACOM.
Alias, agradecendo a ajuda do Henrique.
O professor Pagliosa realmente foi muito "fóda" nesse programa, minha função remove, ficou com pelo menos um terço do que era.

[]'s

quinta-feira, setembro 28, 2006

Os links foram devidamente cancelados pelo Google por motivo de


continuação direta

  • A sintaxe de declaração para atributo de uma classe é:

Atributo:
("MODIFICADOR")* Tipo "ID" Inicializador ? ";"

onde
-MODIFICADOR pode ser uma das seguintes palavras reservadas:
  • public, protected ou private, indicando a visibilidade do atributo(a ausência do atributo invisível do pacote onde a classe é declarada;
  • inal, indicando que o atributo é uma constante, ou seja, seu valor não pode ser modificado;
  • static, indicando que o atributo é um atributo de classe;
-Tipo: NomeDeTipo("[""]")*
NomeDeTipo: Nome | "TIPO_PRIMITIVO"
sendo TIPOPRIMITIVO as palavras reservadas:
boolean, byte, char, double, int, float, long ou short

-Inicializador: define o valor inicial do atributo(obrigatório se o atributo é final). A sintaxe é:
"="(InicializadorSimples | InicializadorDeVetor)
InicializadorSimples:
Expressão
InicializadorDeVetor:
"{" ListaDeExpressões | InicializadorDeVetor)?"}"
ListaDeExpressões:
Expressão (","Expressão)*
ListaDeInicializadorDeVetor: InicializadorDeVetor(","InicializadorDeVetor)*


  • A sintaxe de declaração de um método é:
Método:
("MODIFICADOR")* TipoDeRetorno "ID" "("Parametros?")"
(";" | Bloco)

onde

-MODIFICADOR pode ser uma das seguintes palavras reservadas:
  • public, protected ou private, indicando a visibilidade do método(a ausência do método invisível do pacote onde a classe é declarada
  • final, indicando que o método não pode ser sobrecarregado em classes derivadas. Em Java todos os métodos não estáticos com ecessão dos contrutores são virtuais se a classe foi declarado como final então todos os seus métodos são finais.
  • static, indicando que um método é um método de classe
  • abstract, incicando que um método é abstrato. Neste caso a classe também tem que ser declarada como abstrato. Um método abstrato não pode ser final ou static. Um método abstrato não tem corpo.

-Tipo de Retorno: Tipo | "VOID"
sendo "VOID" void
-Parâmetros:
Lista de Parâmetros do método, cuja sintaze é:
Parâmetro ( "," Parâmetro)*
Parâmetro: "FINAL"? Tipo
sendo "FINAL" a palavra reservada final, indicando que o parâmetro não pode ter seu valor modificado no corpo do método.
-Bloco: onde bloco é o corpo do método, se este não for abstrato. A sintaxe é:
"{" Sentença* "}"

A sintaxe de sentenças e expressões Java são muito similares a do C++, com poucas diferenças.
A sintaxe de declação de um construtor em Java é:
Construtor:
("MODIFICADOR")* "ID" "("Parâmetros?")"
BlocoDoCtor

onde
-MODIFICADOR
  • public, protected ou private, indicando a visibilidade do método(a ausência do método invisível do pacote onde a classe é declarada
-ID é o nome do construtor no qual deve ser idêntico ao nome da classe
-BlocoDoCtor é o corpo do construtor, igual ao corpo de um método. Exceto que a primeira sentença deve ser o Inicializador da super classe se necessário.
"{"
InicializadorDaSuperClasse?
Sentença
"}"
-Inicializador da Super Classe: é um
"SUPER" "(" ListaDeExpressões? ")"";"
sendo "SUPER" a palavra reservada super e ListaDeExpressõe os argumentos para um dos construtores da super classe.

  • Uma unidade de compilação Java, pode ter varias declarações de classe, mas obrigatoriamente deverá ter a declaração de uma classe cujo nome é o mesmo nome da unidade de compilação. Esta classe principal deve ser a única classe pública da unidade de compilação
  • O ponto de entrada de execução de uma aplicação Java é o método cuja assinatura é: static public void main (string[] args) o qual deve ser declarado na classe principal. O parâmetro args são os argumentos passados para o método principal pela linha de comando.
Exercício: Implemente uma lista de objetos em Java. Com as operações de adicionar, procurar, remover, getters, qtddeElemento, clear, etc. Implemente também um iterador para a lista. Linearmente Encadeada.

Exercício: Estude a interface da classe Object (o site da Sun)
Exercício: Estude a interface da classe Integer

terça-feira, setembro 26, 2006

Java

Antes de tudo, clique nos links ai do lado, e entre aqui e clique no banner.


Introdução:
  • Java é uma linguagem de programação de compilador, uma API(Application Programing Interface) e uma máquina virtual.
  • A API Java é uma coleção de pacotes, cada pacote é uma coleção de classes compiladas. A API que acompanha o JDK(Java Development Kit) é bastante grande, o pacote de classes para programação de entrada/saída (inclúi arquivos), estruturas de dados, funções matemáticas, comunicação via rede, interfaces gráficas, acesso a banco de dados, persistência de objetos, programação distribuída, gráficos 2d e 3d, reflexão computacional, web, entre muitas outras. Antes de tentar escrever uma nova classe, procure na API.
  • A máquina virtual Java(JVM, Java Virtual Machine) é um programa responsável pela carga de um arquivo Java compilado e pela execução do código objeto desse arquivo.
  • Java é dito independente de plataforma e arquitetura porque um "programa" Java é executado por outro programa que é a JVM. Então a independência só ocorre se houver uma JVM disponível para determinada plataforma de arquitetura.
  • Java é compilada e interpretada. O compilador Java toma como entrada um programa fonte, codificada em uma arquivo texto, com a extensão ".java" e gera como saída um arquivo com o mesmo nome mas com extensão ".class". Este arquivo contém o código objeto gerado pelo compilador o qual consiste de uma sequência de bytes, cada byte representando uma operação que pode ou não ter outros bytes da sequência como argumentos. Esta sequência de bytes, é chamada de "bytecode". Cada método em uma classe em Java terá o seu bytecode no arquivo ".class". A JVM carrega o arquivo ".class" e interpreta o bytecode.
  • Um arquivo ".java" é denominado unidade de compilação. Em uma unidade de compilação podem ser declarados na ordem:
1- Importação de classes(opcional)
2-Tipos dos quais podem ser classes ou interfaces
  • Uma declaração de classe em Java obedece a seguinte sintaxe:
DeclaraçãoDeClasse:
("MODIFICADOR")* "class" "ID' ("EXTENDS" Nome) ?
"{"

(Membro)*

"}"

onde
-MODIFICADOR pode ser uma das seguintes palavras reservadas
  • public, indicando que a visibilidade da classe é pública, ou seja, pode ser acessada de qualquer outra unidade de compilação(se omitido a visibilidade da classe é restrita a sua unidade de compilação)
  • abstract, indicando que a classe é abstrata.
  • final, indicando que a classe não pode ser derivada, ou seja, não poe ser superclasse de outra.
-class

-ID, é qualquer modificador em Java.

-EXTENDS, é a palavra reservada "extends", a qual se presente deve ser seguida do nome da superclasse sendo declarada. Em Java apenas herança simples é admitida. Se a superclasse não for especificada a classe sendo declarada deriva implicitamente da classe Object. O nome de uma superclasse pode ser qualificado. Um nome qualificado em Java é definido pela seguinte sintaxe:
Nome:
"ID" ( "." "ID")*

-Membro, pode ser um atributo, um construtor, um método ou uma classe interna. Em Java não há destrutor: todo objeto que não pode ser alcançado pela JVM é automáticamente destruído pelo coletor de lixo da máquina virtual.
  • A declaração de uma classe define um novo tipo em relação de tipos primitivos da linguagem.
int (inteiro com sinal de 32 bits)
short (inteiro com sinal de 16 bits)
byte (inteiro com sinal de 8 bits)
long (inteiro com sinal de 64 bits)
float (real de 32 bits)
double (real de 64 bits)
boolean (true ou false)
char (caracter unicode de 2 bytes)

Além destes a palavra reservada void é usada na declaração de métodos que não possuem valor de retorno.
  • Além de classes e tipos primitivos, outros tipos podem ser definidos através de vetores uni ou multidimensionais. Por exemplo, o tipo int[] representa o tipo vetor de inteiros e X[][] representa o tipo vetor de vetor de objetos da classe X. Em Java, uma instância de um tipo vetorado é um objeto daquele tipo, ou seja, um vetor em Java é um objeto.

Cliquem nos links!

Agradeço aos que estão clicando nos links, e pra aumentar ainda mais a arrecadação do saudoso Google, e cliquem aqui para cair em outro blog meu e clicar no banner!

Mais uma vez agradeço!

quinta-feira, setembro 21, 2006

Programinhas em Java

public class MeuNome
{
public static void main( String[] args)
{
for(int i=0; i < args.length; i++)
System.out.println(args[i]);
}
}


public class MeuNome
{
public static void main( String[] args)
{
String nome="";
int length=args.length;
if(length>0)
{
nome=args[0];
for(int i=1; i < length; i++)
nome=nome+' '+args[1];

}
System.out.println(nome);
}
}

Erros no site!

Se puderam notar, quando no código do site tiver coisas entre "<>" o html está eliminando oque tem dentro, logo, em alguns lugares fica por exemplo: template<>, mas deveria ter um Banana entre os "<>". E eu não sei como arrumar. Se alguém souber, de uma ajudinha!
E não esqueçam de clicar nos links ai do lado!
[]'s

Cliquem nos links de anúncio!

Quem puder clicar nos links de anúncio Google ai do lado. Fico grato!

[]'s

terça-feira, setembro 19, 2006

Não somente, estrutura de dados diversas não somente podem ser implementadas em templates em C++, mas também iteradores de estruturas de dados. ..... responsável por "atravessar" um contêiner em uma determinada ordem e para cada elemento visitado de um contêiner disponibilizado para algum tipo de processamento. A ordem de atravessamento depende do tipo de contêiner. Em uma lista por exemplo pode ser do início para o fim ou vice-versa; em uma árvore pode ser em pré-ordem, pós ordem. Há iterators que em adição permitem remoção e adição de elementos no contêiner. No exemplo a seguir é de um template que implementa um iterador de lista linearmente encadeadas, ....., a ordem dos links, ou seja, da cabeça para a cauda. Um iterador sempre possui métodos que informam se ainda há elementos do contêiner a serem visitados e em caso verdadeiro qual é o próximo elemento a ser visitado. Estas operações são definidas no template pelos métodos HasNext e Next

template<>
class ListIteratorImp
{

private:

ListImp<>& List;
T* Cur;

public:

ListIteratorImp( ListImp<>& List): List( List), Cur(Cist.PeekHead())
{}
bool HasNext() const
{

return Cur!= "NULL";

}
T* Next()
{

T* temp= Cur;
if(Cur)

Cur= Cur->Next;

return temp;

}
void Restart()
{

Cur= List.PeekHead();

}

};

Em C++, templates podem também ser moldes de funções como no exemplo a seguir:

template <>
void Print(ListImp<>& List)
{
for(ListIteratorImp<> Lit(List); Lit.HasNext();)
Print(Lit.Next());
}

O template acima é um gerador de funções sendo que, cada função gerada tomo como argumento uma referência para um lista de objetos do tipo T, parâmetro do template, e que usando um iterador atravessa a lista em invoca um método Print responsável por imprimir objetos do tipo T. Note o uso das funções HasNext e Next. Observe também que ao ser gerada a função para um tipo T, uma função Print que toma como argumento um ponteiro para o tipo T deve ter sido anteriormente. O compilador gera uma função a partir de um template quando esta for chamada em alguma expressão e não existir nenhuma função com o mesmo nome, número e tipo de parâmetros definidos manualmente. O exemplo abaixo ilustra:



void Print(Banana*);
ListImp<> bananas;
void main()
{
bananas.Add(new Banana(...));
...
Iterate(bananas, Print);

}

Podemos definir em uma função mais genérica para processamento de uma lista a qual toma como argumento um ponteiro para uma função a ser chamada para cada elemento visitado por um iterador, assim ao invés de ter uma função para imprimir, outra para salvar em arquivo, etc, teremos apenas uma função que toma como argumento a operação a ser realizada, isto opde ser implementado pelo seguinte template:

template<>
void Iterate(ListImp<>& List, void (*func)(T*))
{

for(ListIteratorImp<>& Lit(List); Lit.HasNext();)
(*func)(Lit.Next());
}

O trecho de código a seguir ilustra o uso do template:...Uma alternativa aos métodos HasNext da classe paramétrica ListIteratorImpm, consiste em sobrecarregar os operadores de conversão para inteiro e de pré e pós incremento. Desta forma um objeto do tipo ListIteratorImp<> pode ser implicitamente convertido para inteiro em expressões de testes em sentenças de iteração, for, do e while, dispensando assim o uso de HasNext. Similarmente o próximo elementoa a ser visitado pelo iterador pode ser obtido pelos operadores de incremento, dispensando o uso de Next, a idéia é tornar o código mais parecido com o de laços envolvendo números e portanto mais legível.(note no template ListIteratorImp a sintaxe para distinguir a sobrecarga do operador de pré do de pós incremento.)Com esses operadores sobrecarregados, o template da função iterate pode agora ser escrito como:
template <>
void Print(ListImp<>& List)
{
for(ListIteratorImp<> Lit(List); Lit(); ++Lit)
Print(Lit.Current());
}


operator int()
{

return Cur!='NULL';

}

T* operator ++(int)
{

return Next();

}

T* operator ++()
{

if(Cur)

Cur=Cur->Next;

return Cur;

}
RTTI significa Informações de Tipo em Tempo de Execução, em C++ um tipo é representado por uma estrutura do tipo "typeinfo" a qual é declarada no arquivo de cabeçalho #include <>, em tempo de execução o tipo de uma expressão, e o nome do tipo como o operador typeid. A sintaxe é
typeid(expressão)
typeid(nome de tipo)

O operador typeid retorna o typeinfo como argumento. O método mais útil de typeinfo é name, no qual retorna um ponteiro para .......Ascz.......... contendo um nome do tipo. Por exemplo:
#include <>
#include <> class Banana{....};
int main()
{
printf(typeid(Banana).name());
}
void PrintName(Primitivo2i)* p)
{
cout<< p="=">}
Observação: para contornar um bug do GCC podemos escrever
#include<>
void PrintName(const type_info& info)
{
const char* name= info.name();
while(isdigit(*name))
name++;
cout <<>

}

void PrintName(Primitvo2D* p)
{
if( p==0)
cout << "null";
else
PrintName(typeid(*p));
}

Outro método útil da classe Type_info é o operador de comparação ==.

Os novos operadores de cast, aquele que é relaciona com a DinamicCast o qual tenta converter em tempo de execução a expressão passada como argumento para o tipo entre < >. Se a conversão puder ser feita DinamicCast retorna um ponteiro não nulo. Caso contrário o argumento não pode ser convertido para o tipo especificado. O trecho de código a seguir ilustra:

Primitivo2D* p;
Line2D* l;,br>...
l=dynamic_cast<> (p);
if(l!=0)
ProcessaLinha2D(l);
DinamicCast é a forma segura e que sempre funciona de fazer:

if(typeid(*p)==typeid(Line2D))
l=(Line2D*)p;

nem sempre permitido pelo compilador.

quinta-feira, setembro 14, 2006

Exercício de Programação 3

Implementar uma AVL de elementos de qualquer tipo para o qual os operadores < e == sejam aplicáveis, além do construtor e do operador de cópia. Sua AVL deve implementar pelo menos métodos para:
Adição, remoção, verificação se um elemento contém ou não(booleana), método iteração em pré-ordem, in-ordem e pós-ordem, além disso implemente um iterador para sua AVL o qual deve ser capaz de, a exemplo do que faz o método de iteração, atravessar a coleção em pré-ordem, in-ordem e pós-ordem.

Entregar: 13 de outubro.
Fonte, executável totalmente funcionando e relatório explicando atributo por atributo, método por método. Em Latex de preferência, entregar só o pdf.

Aula 12

template<>
class ListIteratorImp
{

private:

ListImp<>& List;
T* Cur;

public:

ListIteratorImp( ListImp<>& List): List( List), Cur(Cist.PeekHead())
{}
bool HasNext() const
{

return Cur!= "NULL";

}
T* Next()
{

T* temp= Cur;
if(Cur)

Cur= Cur->Next;

return temp;

}
void Restart()
{

Cur= List.PeekHead();

}

};


template <>
void Print(ListImp<>& List)
{
for(ListIteratorImp<> Lit(List); Lit.HasNext();)
Print(Lit.Next());
}

template<>
void Iterate(ListImp<>& List, void (*func)(T*))
{

for(ListIteratorImp<>& Lit(List); Lit.HasNext();)
(*func)(Lit.Next());
}

void Print(Banana*);
ListImp<> bananas;
void main()
{
bananas.Add(new Banana(...));
...
Iterate(bananas, Print);

}




//Esta classe esta alterada, na parte for

template <>
void Print(ListImp<>& List)
{
for(ListIteratorImp<> Lit(List); Lit(); ++Lit)
Print(Lit.Current());
}


operator int()
{

return Cur!='NULL';

}

T* operator ++(int)
{

return Next();

}

T* operator ++()
{

if(Cur)

Cur=Cur->Next;

return Cur;

}

Publicidade

Se alguém notou, há um espaço de Anúncios Google ai do lado! Sempre que entrarem aqui, dê um clique em algum dos anúncios, espere alguns segundos e pronto, estará me ajudando!
Fico grato!

terça-feira, setembro 12, 2006

Aula 11

C++ implementa templates os quais podem ser usados em classes e
funções. Para exemplificar seu uso em classes, sejam as classes
abaixo, as quais representam um elemento de uma lista linearmente
encadeada e a lista propriamente dita:

Ex.
struct Banana
{
float L;
float D;
Banana *Next;

}

class ListBanana
{
public:
ListBanana();
~ListBanana();
void Add(Banana*);
void Remove(Banana*);
int GetNumberOfElements() const;
bool IsEmpty() const;
void Clear();
Banana *PeekHead() const;

private:

Banana *Head;
Banana *Tail;
int NumberOfElements;
ListBanana(const ListBanana&); // Não pode acessar
//os métodos private, logo não há construtor de cópia
ListBanana& operator=(const ListBanana&);

};

void ListBanana :: Clear()
{

while(Head)
{

Banana *temp = Head;
Head = Head -> next;
delete temp;

}
Tail = NumberOfElements = 0;

}


OBS:
Banana b; // Cria objeto


List lb // Cria classe
// classe (instância do template); objeto (instância da classe);

typedef List ListBanana;
ListBanana lb;

Vamos supor agora que se queira implementar uma lista de um
outro tipo qualquer, por exemplo: "Laranja". Sem templates há
duas alternativas:
  1. 1. Replicar a implementação da lista trocando "Banana" por "Laranja". Isto é incoveniente por razões óbvias, dentre as quais, há necessidade de alterações manuais no código replicado, sempre que um novo método seja adicionado a classe ou que algum método já existente seja alterado.
  2. 2. Para evitar a replicação, os elementos de uma lista seriam de classes todas elas derivadas de uma classe chamada:
class ListElement
{
private:
ListElement *Next;
friend class List;

};


Assim, "Banana" e "Laranja" derivariam de "ListElement" e haveria
apenas uma implementeção da classe "List", cujos elementos seria
do tipo "ListElement". O incoveniente é que um objeto do tipo
"List" seria um contêiner de quaisquer objeto do tipo "ListElement",
ou seja, poderíamos ter na mesma lista "Bananas" e "Laranjas".
As vezes é justamente isso que se quer, mas nem sempre.
Quando for este o caso, podemos usar templates.

Uma lista genérica pode ser definida em C++ através do seguinte template:

template
class ListImp
{
public:

ListImp();
~ListImp();
void Add(T*);
void Remove(T*);
int GetNumberOfElements() const;
bool IsEmpty() const;
void Clear();
T *PeekHead() const;
void AddAtHead(T*);

private:
T *Head;
T *Tail;
int NumberOfElements;
ListImp(const ListImp&);
ListImp& operator=(const ListImp&amp;amp;amp;amp;amp;);

}


template
void ListImp :: Clear()
{
while(Head)
{
T *temp = Head;
Head = Head -> next;
delete temp;

}
Tail = NumberOfElements = 0;

}


No exemplo acima, "" é o parâmetro do template, o qual representa
um tipo qualquer chamado "T". Note que no corpo da classe, "T"
é usado para representar o tipo de atributos, valores de retorno de
método e parâmetros de método. Um template pode ter qualquer
número positivo de parâmetros.
Um template de uma classe não é uma classe, mas um molde a
partir do qual o compilador gera uma classe. Gerar uma classe a
partir de um template, significa instanciar o template. Para tal,
basta escrever o nome da classe e fornecer um argumento:

... ListImp ...
Supoe-se que o template seja instanciado somente uma vez pelo compilador. Quando um template é instanciado todo o código definido no molde é gerado trocando-se o parâmetro pelo argumento(no exemplo todo T é trocado por Banana). Veja a analogia:

ListImp <> | B;


Na declaração acima ocorre a criação da classe que representa uma lista de Bananas, se esta ainda não tiver sido criada pelo compilador(instanciação do template) e em seguida a criação de um objeto chamado LB do tipo List da Banana(instanciação da classe).

Instanciação de template é igual a classe e instanciação de classe é igual a objeto

Cada instanciação de um template com diferentes argumentos replica todo o código definido no molde. Isto é oque faríamos manualmente no item 1 listado anteriormente; A vantagem é que a tarefa é executada automaticamente pelo compilador. Mas tenha em mente que a replicação ocorre. Portanto embora seja uma solução interessante em muitos casos templates devem ser usados criteriosamente. No caso de lista os métodos são simples e sua replicação não aumentaria demais o tamanho do programa objeto. Isto não ocorre com tudo, em estruturas que requerem um código mais complexo, como por exemplo AVLs. Nesse caso poderíamos criar uma classe base e implementaria os métodos mais complicados e que operariam sobre um tipo genérico como feito a seguir:

class AVLNode
{
public:
AVLNode* Righ;
AVLNode* Left;
int Balance;

};


class AVLBase
{
private:
AVLNode* Root;
int NumberOfElements;

protected:
void Add(AVLNode* );
...

};



A classe AVLBase implementa as operações de inserção, remoção, e atravessamento de uma AVL considerando que os elementos são do tipo AVLNode. Esses métodos são declarados protegidos em AVLBase.

template <>
class AVLElement: public AVLNode
{
public:
T Value;
...

};


template <>
class AVL: public AVLBase
{
public:
void Add(const TB Value)
{
AVLBase::Add(new AVLElement <> (Value));

}

...

};



O template AVLElement gera classes cujos objetos são nós tipo AVL com valor do tipo T. O template AVL gera classes cujos objetos são AVLs de elementos do tipo T. Note que agora a instanciação desse template não replica o código complicado da estrutura de dados AVL o qual foi implementado em AVLBase.

No template ListImp o tipo T deve ser uma classe que declara como atributo público Next. Esta exigência impede que usemos o ListImp para gerar uma lista de Inteiros por exemplo. Isto pode ser contornado com os seguintes templates:

Template
class List
{
public:

List();
~List();
void Add(T*);
void AddAtHead(T*);
void Remove(T*);
int GetNumerOfElements() const;
bool IsEmpty() const;
void Clear();
T* PeekHead() const;

private:

T* Tail;
T* Head;
int NumberOfElements;
List(const List<>&);
List operator=(const List<>&);
}

O template List gera classes cujos objetos são listas de elementos cujo valor são do tipo T. Supoe-se agora que sobre o tipo T sejam definidas as operações de cópia e comparação(verifique).

terça-feira, setembro 05, 2006

Aula 10 - Templates e RTTI em C++

Aula 01 atualizada com a parte de "Construtor de Cópia".

=]

Templates e RTTI em C++

struct Banana
{
float L;
float D;
Banana* Next;
};
class ListBanana
{
public:
ListBanana();
Add(Banana*);
Remove(Banana*);
int GetNumerOfElements() const;
bool IsEmpty() const;
void Clear();
Banana* PeekHead() const;

private:
Banana* Head;
Banana* Tail;
int NumberOfElements;
ListBanana(const ListBanana&);
ListBanana operator=(const ListBanana&);
}


void
ListBanana::Clear()
{

while(Head)
{
Banana* temp=Head;
Head=Head->Next;
delete temp;
}
int=0;
NumberOfElements
}


Template
class List
{
public:
List();
~List();
void Add(T*);
void AddAtHead(T*);
void Remove(T*);
int GetNumerOfElements() const;
bool IsEmpty() const;
void Clear();
T* PeekHead() const;

private:
T* Tail;
T* Head;
int NumberOfElements;
List(const List< t >&);
List operator=(const List< t >&);
}

Template
void
List< t >::Clear()
{
while(Head)
{
T* tempo=Head;
Head=Head->Next;
delete temp;
}
}
List< banana > |B;
classe...............objeto
(instância do ....(instância da
template)............classe)


Template
class ListImp
{
public:
ListImp();
~ListImp();
void Add(T*);
void AddAtHead(T*);
void Remove(T*);
int GetNumerOfElements() const;
bool IsEmpty() const;
void Clear();
T* PeekHead() const;

private:
T* Tail;
T* Head;
int NumberOfElements;
ListImp(const ListImp&);
ListImp& operator=(const ListImp&);
}

Template
struct ListElement
{
T Value;
ListElement< t >*Next;
ListElement(const T& value):Value(value)
{}
}


Template
class List
{
public:
void Add(const T&);
void AddAtHead(const T&);
bool Remove(const T&);
bool Contains(const T&) const;
bool IsEmpty() const;
void Clear()
void GetNumberOfElements() const;
private:
ListImp< listelement< t >> Imp;
List(const List< t >&);
List& operator= (const List< t > b);

Exercício, implemente os métodos!
};

quinta-feira, agosto 31, 2006

Estou mudando o template do site!

Como podem notar, o template esta sendo trocado! Caso não tenha gostado, guarde tudo oque você acha contigo! =]
Ainda não terminei de arrumar, isso dá um trabalho danado!

Abraços!

terça-feira, agosto 29, 2006

Vou colocar as aulas no site do CACOM também!

Vou começar a colocar as aulas de prog3 no site do CACOM, com o intuito de divulgação do site! Por enquanto será aqui e lá. Coloquei apenas a primeira aula!

Pra quem quiser dar uma olhada, Site CACOM
Entre em Recursos, depois em Prog3.

[]'s

Aula 8 e Aula 9

Seguinte, faltei a última aula, e a aula de hj eu vou colocar oque ele passou na última aula!






#if !defined(__Exception_h)
#define __Exception_h

//[]------------------------------------------------------------------------[]
//| |
//| Object Structural WorkBench Class Library |
//| Version 2.0 |
//| |
//| Copyright® 1999-2004, Paulo Aristarco Pagliosa |
//| All Rights Reserved. |
//| |
//[]------------------------------------------------------------------------[]
//
// OVERVIEW: Exception.h
// ========
// Class definition for generic exception.

#if !defined(__lstring_h)
#include "lstring.h"
#endif


//////////////////////////////////////////////////////////
//
// Exception: generic exception class
// =========
class Exception
{
public:
// Constructors
Exception();
Exception(const Exception&);
Exception(const String&);

String GetMessage() const;
operator const CHAR_T*() const;

protected:
String Message;

private:
Exception& operator =(const Exception&);

}; // Exception


//////////////////////////////////////////////////////////
//
// OutOfRangeException: out of range exception class
// ===================
class OutOfRangeException: public Exception
{
public:
OutOfRangeException();
OutOfRangeException(const String&);

}; // OutOfRangeException


//////////////////////////////////////////////////////////
//
// IndexOutOfBoundsException: index out of bounds exception class
// =========================
class IndexOutOfBoundsException: public Exception
{
public:
IndexOutOfBoundsException();
IndexOutOfBoundsException(const String&);

}; // IndexOutOfBoundsException


//////////////////////////////////////////////////////////
//
// ClassNotFoundException: class not found exception
// ======================
class ClassNotFoundException: public Exception
{
public:
// Constructor
ClassNotFoundException(const String&);

}; // ClassNotFoundException


//////////////////////////////////////////////////////////
//
// IOException: IO exception
// ===========
class IOException: public Exception
{
public:
// Constructors
IOException();
IOException(const String&);

}; // IOException


//////////////////////////////////////////////////////////
//
// Exception inline implementation
// =========
inline
Exception::Exception()
{}

inline
Exception::Exception(const Exception& e):
Message(e.Message)
{}

inline
Exception::Exception(const String& message):
Message(message)
{}

inline String
Exception::GetMessage() const
{
return Message;
}

inline
Exception::operator const CHAR_T*() const
{
return (const CHAR_T*)Message;
}


//////////////////////////////////////////////////////////
//
// OutOfRangeException inline implementation
// ===================
inline
OutOfRangeException::OutOfRangeException():
Exception(STRING_C("Out of range exception"))
{}

inline
OutOfRangeException::OutOfRangeException(const String& message):
Exception(message)
{}


//////////////////////////////////////////////////////////
//
// IndexOutOfBoundsException inline implementation
// =========================
inline
IndexOutOfBoundsException::IndexOutOfBoundsException():
Exception(STRING_C("Index out of bounds exception"))
{}

inline
IndexOutOfBoundsException::IndexOutOfBoundsException(const String& message):
Exception(message)
{}


//////////////////////////////////////////////////////////
//
// ClassNotFoundException inline implementation
// ======================
inline
ClassNotFoundException::ClassNotFoundException(const String& className)
{
Message = String(STRING_C("Class not found exception: ")) + className;
}


//////////////////////////////////////////////////////////
//
// IOException inline implementation
// ===========
inline
IOException::IOException()
{
Message = STRING_C("IO exception");
}

inline
IOException::IOException(const String& message):
Exception(message)
{}


#endif







//[]------------------------------------------------------------------------[]
//| |
//| Object Structural WorkBench Class Library |
//| Version 2.0 |
//| |
//| Copyright® 1999-2004, Paulo Aristarco Pagliosa |
//| All Rights Reserved. |
//| |
//[]------------------------------------------------------------------------[]
//
// OVERVIEW: lstring.cpp
// ========
// Class definition for string.

#if !defined(__Exception_h)
#include "Exception.h"
#endif

#define MIN_STRBUF_SIZE 4

//
// Roundup string body size
//
inline int
RoundupSize(size_t size)
{
return (size + MIN_STRBUF_SIZE - 1) & -MIN_STRBUF_SIZE;
}


//////////////////////////////////////////////////////////
//
// StringBody implementation
// ==========
StringBody* StringBody::EmptyString = StringBody::New(STRING_C(""));

void*
StringBody::operator new(size_t size, size_t length)
{
return ::operator new(RoundupSize(size + (length + 1) * sizeof(CHAR_T)));
}

StringBody*
StringBody::New(const CHAR_T* s)
{
return s == 0 ? New() : New(s, STRLEN(s));
}

StringBody*
StringBody::New(const CHAR_T* buffer, int length)
{
StringBody* body = New(length);

STRNCPY(body->StringBuffer(), buffer, length);
body->StringBuffer()[length] = 0;
return body;
}

StringBody*
StringBody::Append(StringBody* s)
{
if (s->IsEmpty())
return this->MakeUse();
if (this->IsEmpty())
return s->MakeUse();

StringBody* body = New(this->StringBuffer(), this->Length + s->Length);

STRCPY(body->StringBuffer() + this->Length, s->StringBuffer());
return body;
}

int
StringBody::Compare(StringBody* s)
{
return this == s ? 0 : STRCMP(StringBuffer(), s->StringBuffer());
}

const CHAR_T&
StringBody::operator [](int i)
{
if (i <>= Length)
throw OutOfRangeException();
return StringBuffer()[i];
}

int
StringBody::IndexOf(CHAR_T c) const
{
const CHAR_T* stringBuffer = (const CHAR_T*)(*this);
const CHAR_T* indexPointer = STRCHR(stringBuffer, c);

return indexPointer ? indexPointer - stringBuffer : - 1;
}

int
StringBody::LastIndexOf(CHAR_T c) const
{
const CHAR_T* stringBuffer = (const CHAR_T*)(*this);
const CHAR_T* indexPointer = STRRCHR(stringBuffer, c);

return indexPointer ? indexPointer - stringBuffer : - 1;
}

StringBody*
StringBody::Reverse()
{
if (this->IsEmpty())
return New();

CHAR_T* thisBuffer = StringBuffer();
StringBody* body = New(Length);
CHAR_T* bodyBuffer = body->StringBuffer();

for (int n = Length; n;)
*bodyBuffer++ = thisBuffer[--n];
*bodyBuffer = 0;
return body;
}

StringBody*
StringBody::ToLower()
{
if (this->IsEmpty())
return New();

CHAR_T* thisBuffer = StringBuffer();
StringBody* body = New(Length);
CHAR_T* bodyBuffer = body->StringBuffer();

for (int i = 0; i < Length; ++i)
bodyBuffer[i] = (CHAR_T)TOLOWER(thisBuffer[i]);
return body;
}

StringBody*
StringBody::ToUpper()
{
if (this->IsEmpty())
return New();

CHAR_T* thisBuffer = StringBuffer();
StringBody* body = New(Length);
CHAR_T* bodyBuffer = body->StringBuffer();

for (int i = 0; i <>Length; ++i)
bodyBuffer[i] = (CHAR_T)TOUPPER(thisBuffer[i]);
return body;
}


//////////////////////////////////////////////////////////
//
// String implementation
// ======
String&
String::Copy(const String& s, int copy)
{
Body->Delete();
Body = copy == DeepCopy ? StringBody::New(s.Body) : s.Body->MakeUse();
return *this;
}

CHAR_T
String::operator [](int i) const
{
return (*Body)[i];
}

CHAR_T&
String::operator [](int i)
{
return const_cast((*Body)[i]);
}

String
String::ToString(CHAR_T c)
{
CHAR_T s[2];

s[0] = c;
s[1] = 0;
return String(s);
}

String
String::ToString(int i)
{
CHAR_T s[16];

#if defined __LINUX
SPRINTF(s, sizeof(s) / sizeof(CHAR_T) - 1, STRING_C("%d"), i);
#else
SPRINTF(s, STRING_C("%d"), i);
#endif
return String(s);
}

String
String::ToString(double d)
{
CHAR_T s[64];

#if defined __LINUX
SPRINTF(s, sizeof(s) / sizeof(CHAR_T) - 1, STRING_C("%lf"), d);
#else
SPRINTF(s, STRING_C("%lf"), d);
#endif
return String(s);
}

String
String::ToString(bool b)
{
return String(b ? STRING_C("true") : STRING_C("false"));
}








#if !defined(__lstring_h)
#define __lstring_h

//[]------------------------------------------------------------------------[]
//| |
//| Object Structural WorkBench Class Library |
//| Version 2.0 |
//| |
//| Copyright® 1999-2004, Paulo Aristarco Pagliosa |
//| All Rights Reserved. |
//| |
//[]------------------------------------------------------------------------[]
//
// OVERVIEW: lstring.h
// ========
// Class definition string.

#include
#include
#include
#include

#if defined __UNICODE
#define CHAR_T wchar_t
#define STRING_C(s) L##s
#if defined __LINUX
#include
#include
#endif
#define STRLEN wcslen
#define STRCPY wcscpy
#define STRNCPY wcsncpy
#define STRCMP wcscmp
#define STRNCMP wcsncmp
#define STRCHR wcschr
#define STRRCHR wcsrchr
#define TOUPPER towupper
#define TOLOWER towlower
#define PRINTF wprintf
#define SPRINTF swprintf
#define VSPRINTF vswprintf
#else
#define CHAR_T char
#define STRING_C(s) s
#if defined __LINUX
#define SPRINTF snprintf
#define VSPRINTF vsnprintf
#else
#define SPRINTF sprintf
#define VSPRINTF vsprintf
#endif
#define STRLEN strlen
#define STRCPY strcpy
#define STRNCPY strncpy
#define STRCMP strcmp
#define STRNCMP strncmp
#define STRCHR strchr
#define STRRCHR strrchr
#define PRINTF printf
#define TOUPPER toupper
#define TOLOWER tolower
#endif

//
// Constants
//
enum
{
ShallowCopy,
DeepCopy
};

//
// Forward definition
//
class StringBody;


//////////////////////////////////////////////////////////
//
// String: string class
// ======
class String
{
public:
// Constructors
String();
String(const String&);
String(const String&, int);
String(const CHAR_T*);
String(const CHAR_T*, int);

// Destructor
~String();

// Assignment
String& Copy(const String&, int = ShallowCopy);
String& operator =(const String&);
String& operator =(CHAR_T);
String& operator =(int);
String& operator =(double);
String& operator =(bool);

// Concatenation
String operator +(const String&) const;
String operator +(CHAR_T) const;
String operator +(int) const;
String operator +(double) const;
String operator +(bool) const;
String& Append(const String&);
String& operator +=(const String&);
String& operator +=(CHAR_T);
String& operator +=(int);
String& operator +=(double);
String& operator +=(bool);

// Comparison
int Compare(const String&) const;
bool operator ==(const String&) const;
bool operator !=(const String&) const;

// Subscripting
CHAR_T operator [](int) const;
CHAR_T& operator [](int);

// Character set searching
int IndexOf(CHAR_T) const;
int LastIndexOf(CHAR_T) const;

// Miscellaneous
operator const CHAR_T*() const;
int Length() const;
String& Reverse();
String& ToLower();
String& ToUpper();

// Static casting
static String ToString(CHAR_T);
static String ToString(int);
static String ToString(double);
static String ToString(bool);

private:
StringBody* Body; // this is the body

// Private constructor
String(StringBody*);

}; // String


//////////////////////////////////////////////////////////
//
// StringBody: string body class
// ==========
class StringBody
{
public:
// Free string body memory
void operator delete(void*, size_t);

private:
int RefCount;
int Length; // string buffer length

static StringBody* EmptyString;

// Constructor
StringBody(int = 0);

// Allocate memory to store a string body
void* operator new(size_t, size_t);

// Is this string body the empty string?
bool IsEmpty() const;

// Static "constructors"
static StringBody* New();
static StringBody* New(StringBody*);
static StringBody* New(int);
static StringBody* New(const CHAR_T*, int);
static StringBody* New(const CHAR_T*);

// Make a shallow-copy of this string body
StringBody* MakeUse();
// Delete this string body
void Delete();

// Get the string buffer of this string body
operator const CHAR_T*() const;
CHAR_T* StringBuffer();

// Get the character of this string body at the specified index
const CHAR_T& operator [](int);

// Get the index within this string body of the specified character
int IndexOf(CHAR_T) const;
int LastIndexOf(CHAR_T) const;

// Append another string body to this string body
StringBody* Append(StringBody*);
// Compare this string body to another
int Compare(StringBody*);
// Reverse the string buffer of this this string buffer
StringBody* Reverse();
// Convert this string body to lowercase
StringBody* ToLower();
// Convert this string body to uppercase
StringBody* ToUpper();

friend class String;

}; // StringBody


//////////////////////////////////////////////////////////
//
// StringBody inline implementation
// ==========
inline void
StringBody::operator delete(void* ptr, size_t)
{
::operator delete(ptr);
}

inline
StringBody::StringBody(int length):
RefCount(1),
Length(length)
{}

inline bool
StringBody::IsEmpty() const
{
return this == EmptyString;
}

inline StringBody*
StringBody::New()
{
return EmptyString->MakeUse();
}

inline StringBody*
StringBody::New(StringBody* s)
{
return s->IsEmpty() ? New() : New(s->StringBuffer(), s->Length);
}

inline StringBody*
StringBody::New(int length)
{
return new(length) StringBody(length);
}

inline StringBody*
StringBody::MakeUse()
{
++RefCount;
return this;
}

inline void
StringBody::Delete()
{
if (!--RefCount)
delete this;
}

inline
StringBody::operator const CHAR_T*() const
{
return reinterpret_cast(this + 1);
}

inline CHAR_T*
StringBody::StringBuffer()
{
return const_cast((const CHAR_T*)*this);
}


//////////////////////////////////////////////////////////
//
// String inline implementation
// ======
inline
String::String()
{
Body = StringBody::New();
}

inline
String::String(const String& s)
{
Body = s.Body->MakeUse();
}

inline
String::String(const String& s, int copy)
{
Body = copy == DeepCopy ? StringBody::New(s.Body) : s.Body->MakeUse();
}

inline
String::String(const CHAR_T* s)
{
Body = StringBody::New(s);
}

inline
String::String(const CHAR_T* s, int len)
{
Body = StringBody::New(s, len);
}

inline
String::String(StringBody* body)
{
Body = body;
}

inline
String::~String()
{
Body->Delete();
}

inline String&
String::operator =(const String& s)
{
return Copy(s);
}

inline String&
String::operator =(CHAR_T c)
{
return operator =(ToString(c));
}

inline String&
String::operator =(int i)
{
return operator =(ToString(i));
}

inline String&
String::operator =(double d)
{
return operator =(ToString(d));
}

inline String&
String::operator =(bool b)
{
return operator =(ToString(b));
}

inline String
String::operator +(const String& s) const
{
return String(Body->Append(s.Body));
}

inline String&
String::Append(const String& s)
{
return operator =(operator +(s));
}

inline String&
String::operator +=(const String& s)
{
return Append(s);
}

inline String&
String::operator +=(CHAR_T c)
{
return Append(ToString(c));
}

inline String&
String::operator +=(int i)
{
return Append(ToString(i));
}

inline String&
String::operator +=(double d)
{
return Append(ToString(d));
}

inline String&
String::operator +=(bool b)
{
return Append(ToString(b));
}

inline int
String::Compare(const String& s) const
{
return Body->Compare(s.Body);
}

inline bool
String::operator ==(const String& s) const
{
return Compare(s) == 0;
}

inline bool
String::operator !=(const String& s) const
{
return !operator ==(s);
}

inline int
String::IndexOf(CHAR_T c) const
{
return Body->IndexOf(c);
}

inline int
String::LastIndexOf(CHAR_T c) const
{
return Body->LastIndexOf(c);
}

inline int
String::Length() const
{
return Body->Length;
}

inline
String::operator const CHAR_T*() const
{
return (const CHAR_T*)*Body;
}

inline String&
String::Reverse()
{
return operator =(String(Body->Reverse()));
}

inline String&
String::ToLower()
{
return operator =(String(Body->ToLower()));
}

inline String&
String::ToUpper()
{
return operator =(String(Body->ToUpper()));
}


#endif

terça-feira, agosto 22, 2006

Aula 7, no final da Aula 2 [update]

A suposta aula 7, que seria a de hj, eu coloquei no final da Aula 2, "Atributos de métodos e classes"! Por orientação do professor! É uma continuação!
[]'s

quinta-feira, agosto 17, 2006

Arrumei os comentários!

Eu não sei se alguém já tentou comentar alguma coisa aqui, mas agora eu arrumei a parada!

[]'s

Aula 6

continuação direta da aula 5
Uma instância de uma classe com métodos virtuais possui em sua estrutura, além dos atributos declarados na classe, um ponteiro para a TPMV da classe(espaço para esse ponteiro é alocado pelo compilador). Por exemplo,

A* pa=new A(); //construtor padrão

|_&A::TPMV_|<-----------|__|pa
|____a_____|


pa=new B();

|_&B::TPMV_|<----------|__|pa
|___A::a____|
|___B::b____|
|___B::c____|


O acoplamento do método à mensagem pa->f(); em C++ é feito da seguinte forma:
  • O endereço da TPMV do objeto apontado por "pa" é obtido(é o primeiro campo do objeto);
  • O endereço do método a ser acoplado é obtido da TPMV e corresponde à entrada do índice do método virtual f()(neste caso 0(zero));
  • Os argumentos do método e "this" são empilhados e o método é finalmente invocado: (*(pa->TPMV[0]))(pa) //(* (endereço de TPMV[índice de f()]))( this)
O grande benefício da junção posterior é cófigo novo funcionando com código velho eliminando construções do tipo switch case, um método Figura2d::Desenha() ilustra isso
class Figura2D
{
private:
Primitivo2D& Primitivo;
int NDPr;
public:
void AdicionaPrimitivo(Primitivo);
void Desenha() const;
Figura2D();
Primitivo(0);
NDPr(0);
};

void Figura2D::Desenha() const
{
for(Primitivo2D* p=Primitivo; p; p=p->Prox)
p->Desenha();
}

O método irá funcionar para qualquer objeto cuja classe derivada de Primitivo2D() e sobrecarregar o método abstrato Primitivo2d::Desenha(). Estamos falando não apenas das classes Linha2D e Círculo2D, mas de qualquer classe derivada de Primitivo2D.
Obs Um método abstrato em c++ é um método virtual puro. Toda classe que declarar pelo menos um métodos abstrato é uma classe abstrata. Uma classe abstrata não admite instância.( Em java, uma classe pode ser declarada abstrata mesmo se possuir um método abstrato, porém, se uma classe possuir um método abstrato, então também deve ser declarado abstrato)

terça-feira, agosto 15, 2006

Aula 5

Polimorfismo é a capacidade de um operador ou de métodos de um mesmo nome implementar várias operações distintas. Em C++, por exemplo, o operador '+' é usado para adição de dois inteiros, de dois reais, de um real e um inteiro, etc. Em Java, o operador também é usado para concatenação de strings. Além disso, em C++, é possível a sobrecarga de operadores, ou seja, a definição de funções cujo nome é a palavra reservada 'operator' seguida do símbolo do operador(os argumentos da função devem ser compatíveis com o número de argumentos exigidos pelo operador). Assim, pode se escrever em C++
X operator +(const X&, const X&amp;amp;);
Oque aumenta ainda mais o polimorfismo do operador '+' o qual passa a ser usado também para a adição de dois objetos da classe X:
X x1, x2, x3;
.
.
.
x3=x1+x2;
x3=operator+(x1, x2);

css X
{.
.
.
friend X operator+(const X&, const X&amp;amp;);
.
.
.
};


class X
{
public:
X operator+(const X&) const;
.
.
.
};
x3=x1+x2;
x3=x1.operator+(x2);


No caso de polimorfismo envolvendo funções que não sejam operadores, possam ter funções ou métodos com o mesmo identificador mas que são distinguidos pelo número e/ou tipo dos parametros. Como exemplo sejam os métodos da classe A:
Sejam os métodos da classe A:

class A
{
int a;
public:
virtual void f();
void f(int);
void f(int, float);
void f(float, int);
};

Há quatro versões do método f na classe. No exemplo a seguir os métodos acoplados as respectivas mensagens são determinados em tempo de compilação em função do número e/ou tipo dos argumentos da mensagem. Quando o acoplamento mensagem/metódo é resolvido em tempo de compilação é chamado "acoplamento estático" ou "junção anterior".

A a;
a.f(); //A::f()
a.f(2); //A::f(int)
a.f(2, 3); //O compilador não sabe, não há um método f(int, int)

Na classe A tinhamos quatro versões de um método declarado, ou seja, uma instância de A pode responder a quatro tipos distintos de mensagens cujo seletor é f. A uma outra faceta de polimorfismo relacionada com o mecanismo de herança. Uma classe derivada, pode redefinir um método de uma classe base, com o mesmo identificador, como mesmo tipo de identificador, mesmo tipo de retorno e um corpo que pode ser diferente. Isto é feito na classe B a seguir, derivada da classe A:

class B: public A
{
int b, c;
public:
void f();
void f(int);
};

Note que uma instância de B pode responder a 6 mensagens cujo seletor é f, quatro para métodos herdados de A, e dois para métodos redefinidos em B.
Em C++ para mensagens enviadas a um objeto criado estáticamente, o acoplamento sempre será estático como no exemplo abaixo:

B b;
b.f(); //B::f()
b.f(2); //B::f(int)
b.A::f() //A::f() Nome qualificado

**** IMPORTANTÍSSIMO ****
As coisas mudam quando uma mensagem é enviada a um objeto através de um ponteiro. Em C++ e em Java um ponteiro para uma classe base pode receber um endereço de um objeto desta classe ou de qualquer classe que dela derivada direta ou indiretamente. Assim, se tivermos

A* pa;
.
.
.
pa->f(); //A::f()

podemos nos perguntar qual método será acoplado à mensagem, uma vez que o ponteiro pa pode receber o endereço de um objeto da classe A, da classe B ou de qualquer outra que derive de A. A resposta a essa questão depende do método A::f() ser virtual ou não:
  • Se o método não for virtual, então A::f() será acoplado(independentemente do tipo do objeto cujo endereço é atribuido a pa), uma vez que pa é um ponteiro para a classe A, ou seja, o acoplamento é estático(determinado em tempo de compilação). [Se não for virtual vai ser estático, foda-se oque aconteça. Nota do professor]
  • Se um método for virtual então o método a se acoplado a mensagem será aquele da classe do objeto cujo endereço, em tempo de execução, for atribuido a pa. Este tipo de acoplamento é chamado "acoplamento dinâmico" ou" junção posterior", pois é resolvido em tempo de execução.
**********************

Observações:
  1. Em uma classe derivada a redefinição de um método não virtual herdado de uma classe base esconde um método da classe base. A redefinição de um método virtual na classe derivada sobrecarrega um método da base.
  2. Em Java, todos os métodos não estáticos são virtuais.
  3. Acoplamento dinâmico tem um custo em termos de eficiência. Em C++ a junção posterior é implementada através de tabelas de ponteiros de métodos virtuais(TPMV). Toda classe que tiver declarado pelo menos um método virtual terá associada uma tabela cujas entradas serão os endereços do código de cada uma das funções virtuais declaradas na classe. Toda função virtual possui como atributo um índice para a entrada correspondente na TPMV de sua classe. A TPMV de uma classe derivada copia a TPMV de sua classe base, ajustando as entradas para apontar para aqueles métodos que foram sobrecarregados e foram adicionando novas entradas se novos métods virtuais forem declarados da classe derivada. Por exemplo a TPMV da classe A é:
A
0| &A::f() |
1 | &A::f(int, float) |

A TPMV da classe B é:
B
0 | &B::f() |
1 | &amp;amp;A::f(int, float) |
2 | &B::k() |

sexta-feira, agosto 11, 2006

Apostilas sobre Java!

Seguinte pessoal, tenho aqui comigo algumas apostilas sobre Java que poderiam vir a ser interessantes, eu não li direito nenhuma, mas se tiver alguém afim, eu upo elas pra algum lugar.
As apostilas são:
  1. O que é Java?
  2. JavaScript
  3. Apostila JAVA
  4. Guia de Referência
  5. Exemplos(obviamente de Java)
Mais uma vez, se alguém se mostrar interessado eu as disponibilizarei!

Também tenho apostilas de Algoritmos, VB, Access, ASP, Assembly, BD, C, CGI, Clipper, Delphi, Design Gráfico, Eng. de Soft. , Hardware, HTML, Internet, JSP, Office, Pascal, Perl, PHP, Python, Rede, Segurança, SO, StarOffice e Unix. Vale lembrar que eu não li nenhuma delas!

Qualquer coisa, jamildagher@gmail.com

quinta-feira, agosto 10, 2006

Aula 4

Exemplo de polimorfismo:

class A
{
int a;
public:
void f();
void f(int);
void f(int, float);
void f(float, int);
};

A a;
a.f(); //A::f()
a.f(2); //A::f(int)
a.f(2, 3); //O compilador não sabe, não há um método f(int, int)


class B: public A
{
int b, c;
public:
void f();
void f(int);
};


B b;
b.f(); //B::f()
b.f(2); //B::f(int)
b.A::f() //A::f() Nome qualificado

class A
{
public:
virtual void f();
void f(int);
void f(in, float);
void f(float, int);
}; //Não alterou as respostas

retorna a classe A sem o virtual void
A* pa;
.
.
.
pa->f(); //A::f()


B* bp;
.
.
.
bp->f(); //B::f()




//Exemplos

class Primitivo2D
{
public:
virtual void Desenha() cont=0;
private:
Primitivo2D* Prox;
friend class Figura2D;
};

class Linha2D: public Primitivo2D
{
public:
void Desenha() const;
.
.
.
};

class Circulo2D: public Primitivo2D
{
public:
void Desenha() const;
.
.
.
};

class Figura2D
{
private:
Primitivo2D& Primitivo;
int NDPr;
public:
void AdicionaPrimitivo(Primitivo);
void Desenha() const;
Figura2D();
Primitivo(0);
NDPr(0);
};

void Figura2D::Desenha() const
{
for(Primitivo2D* p=Primitivo; p; p=p->Prox)
p->Desenha();
}


//void main
Figura2D f;
f.AdicionaPrimitivo(new Linha2D(...));
f.AdicionaPrimitivo(new Circulo2D(...));
.
.
.
f.Desenha();

void Figfura2D::AdicionaPrimitivo(Primitivo2D* p)
{
p->Prox=Primitivo;
Primitivo=p;
++NDPr;
}

terça-feira, agosto 08, 2006

Aula 3 já corrigida!

A PARTE ERRADA JÁ FOI CORRIGIDA. Agradecimentos a Letrícia e a Cristiane.

O desenho eu irei mudá-lo assim que me vier uma inspiração, por enquanto fica esse desenho em ASCII tosco!
Abraço a todos! E espero estar ajudando!

Aula 3

-> Propriedades da Orientação e Objeto

  • Encapsulamento
Encapsular significa esconder, na definição de uma classe os membros que representam a estrutura e o comportamento interno dos objetos da classe. Geralmente são escondidos todos os atributos enquanto os métodos são tornados publicos. Entretanto pode-se esconder também métodos bem como tornar públicos atributos. Tudo depende do projeto e do bom senso.

"Esconder um membro" em C++ significa declaralo na sessão privada(private) ou protegida(protected) da classe. Um membro privado só pode ser acessado em métodos da prórpia classe onde foi declarado. Membros protegidos podem ser acessados por métodos da própria classe e de classes derivadas publicamente da classe onde foi declarada. Membros públicos podem ser acessados por quaisquer métodos e definem a interface da classe.

Para um atributo privado ou protegido o acesso a este só pode ser efetuado por métodos quaisquer indiretamente, através de métodos declarados na classe do atributo chamados "setters" e "getters". Um setter é utilizado para atribuição de um novo valor para um atributo, enquanto um getter é utilizado para a obtenção de um valor.

Um atributo para o qual há um getter e um setter é uma propriedade do objeto. Embora aconselhável esconder um atributo, seu acesso por getters e setters(ou seja, funções) podem acrescentar ineficiência ao sistema. Em C++ tal ineficiência é evitada com o uso de métodos "in-line". Em uma mensagem na qual o método in-line é aclopado, não há um overhead(custo) de uma chamada de função. Ao invés disso o corpo do métodos é expandido em linha no local da mensagem. Com isso o código gerado fica maior dependendo do tamanho do corpo do método corrente, por isso, métodos in-line tem que ser criteriosamente usados. Em C++ todo método implementado dentro de sua classe é inline. Métodos implementados fora da classe tem que ser explicitamente declarados com a palavra inline. De fato o compilador tenta fazer o método in-line se possível ( Ou seja, nem todo método declarado in-line é efetivamente inline ).

As vantagens do encapsulamento são:
  1. Melhor organização do cógigo.
  2. Alterações em membros encapsulados de uma classe não são refletidas nos métodos de outros objetos usuários da classe(a não ser que essas alterações modifiquem a interface da classe).

  • Herança
Mecanismo através do qual um objeto de uma classe Y herda todos os membros de uma classe X. A classe X é chamada SuperClasse(ou classe Base em C++) e a classe Y é chamada SubClasse ou classe Derivada. Uma classe Base representa uma generalização, uma classe Derivada representa uma especialização. Em UML(Unified Modeling Language, Linguagem de Modelagem Unificada) a representação mais simples de uma classe é um retângulo com o nome da classe dentro. Um relacionamento do tipo generalização/especialização entre duas classes é expresso em UML através do seguinte diagrama de classe:
..__
| X |
../ ...|
..__
| Y |

Há quatro maneiras de uma classe Derivada especializar uma classe Base:
  1. Adicionando novos atributos
  2. Adicionando novos métodos
  3. Redefinindo a implementação de métodos herdados da classe Base
  4. Não fazendo nada
O grande benefício da herança é reutilização de código.
Obs. Ao contrário de Java, C++ admite herança multipla, isto é, uma classe pode ser Derivada de duas ou mais classes Bases.

  • Polimorfismo(várias formas)

terça-feira, agosto 01, 2006

Aula 2

Aula 02


Exemplo
{

X x;
}


Alocação Dinâmica

Em C++ um objeto é criado dinâmicamente, com o operador new o qual retorna o endereço da região de memória do primeiro byte ocupado pelo objeto.

X* p=new X(); ou X *p=new X;

Objetos criados dinâmicamente residem no heap do sistema,que é a área destinada a um programa pelo SO(sistema operacional) para alocação dinâmica(em tempo de execução de memória). Ao contrário de objetos estáticos, os objetos criados dinâmicamente devem ser explicitamente destruidos, através do operador delete. Ao contrário de new, delete invoca o destrutor e em seguida libera a memória do heap ocupada pelo objeto.

delete p;

Obs. Manipulação explicita de ponteiros é uma das causas mais comuns de erros em C++(coisa que não existe em Java).

O tempo de vida útil de um objeto começa imediatamente após sua criação e dura até o instante imediatamente antes de sua instrução. Durante sua vida útil o objeto pode ser usado de duas maneiras:

1- Acessando um atributo do objeto:

int a=x.a; //acesso de leitura: x.a é um rvalue (valor que esta dp lado direito, não pode ser modificado)
p->a=a; //acesso de escrita: p->a é um lvalue (trabalha com o endereço)
//mesma coisa que a de cima (*p).a=a;

2- Enviando uma mensagem para o objeto:

x.m();
p->m();

Como resposta à mensagem o receptor acopla o método

X::m() //X(qualificador) e X::m(nome qualificado).

Acoplar significa: descobrir na classe do receptor um método cujo nome é o mesmo do seletor da mensagem e cujos parâmetros casam em número e tipo com os argumentos da mensagem, e em seguida invocar tal método. Sintaticamente enviar uma mensagem é similar a acessar um atributo, com a diferença que depois do nome do método vem o par de parênteses com os argumentos da mensagem em seu interior. É como se estivessemos chamando um função para um objeto. Semânticamente porém deve se ter em mente que se esta enviando uma mensagem e que a função a ser invocada é consequência do acoplamento.

Obs. X::m é um nome qualificado sendo o nome simples 'm' o nome de um método(o nome simples de um nome qualificado pode ser o nome de qualquer membro de uma classe). O qualificador de um nome qualificado é um nome de classe que precede o operador de escopo, nesse caso o 'X'. “m é da classe X”

Em C++, o operador de escopo ::a é um nome totalmente qualificado, sendo 'a' um nome declarado globalmente(o qualificador é nulo).

Exemplo
int a;
void f(int a)
{
::a=a;
}

Propriedades da Orientação e Objeto

-> Encapsulamento
-> Herança
-> Polimorfismo

Atributos de Métodos de Classes

Ao contrário de atributo de instância,um atributo de classe não pertence à estrutura de dados de objetos da classe. Há apenas uma cópia do atributo(que pode ser intendido como sendo de propriedade da classe) ao invés de uma cópia para cada objeto da classe. Os objetos da classe compartilham esta cópia única. Em C++ um atributo de classe é definido como modificador "static".

Obs Em C++ a variável uma variável estática declarada em uma classe(geralmente em uma arquivo .h) é definida em um arquivo .cpp.

//
//Início do x.h
//
#include

class X
{
public:
int a, b;
static int sa; //atributo de classe

void f()
{
a=sa;
}

};

//
//Fim do x.h
//

//
//Início do x.cpp
//
#include "x.h"

int X::sa=4;
int main()
{
X x1, x2;
int a=x1.a;

a=X::sa;
x1.sa=3;
printf("Tamanho de x: %d, valor de X::sa: \n", sizeof(x1), X2.sa);
return 0;
}

//
//Fim do x.cpp
//

Um método de classe:

  • não pode ser invocado como resultado do acoplamento mensagem método.
  • não pode acessar atributos de instância de "this"(Não é possível usar this em um método de classe).
  • é como se fosse uma função global pertencente à classe. Em C++ um método de classe é declarado como modificador "static".
Tratamento de Exceções

O tratamento de exceções constitui-se em:
  1. Lançamento da exceção. Quando um método verifica a ocorrência de uma situação excepcional, este pode lançar uma exceção. Lançar uma exceção significa criar um objeto que transportará em seus atributos(conforme definido em sua classe) com as informações relevantes sobre a exceção detectada. Uma vez criado este objeto ele é lançado em uma sentença "throw". Em C++ uma exceção pode ser um objeto de qualquer tipo. Em Java uma exceção é uma instância que o objeto da classe "Exception" ou dela derivado. O código abaixo da sentença "throw" não é executado quando no lançamento da exceção.
  2. Tratamento da exceção propriamente dito. Todo código em que uma exceção pode ocorrer deve ser enclausurado em um bloco "try". Se em algum ponto do "try" uma exceção for lançada, o código restante após o ponto de lançamento não é executado. Após o bloco "try" deve se ter uma ou mais blocos "catch", parametrizados cada um deles com um dos tipos de exceção que podem ocorrer no "try". Na ocorrência de uma exceção o fluxo de controle é transferido para o primeiro bloco "catch" cujo parâmetro é do tipo da exceção lançada. O código do "catch" efetua o tratamento da exceção, e o fluxo de controle é desviado para o código após o último "catch". Senão houver um "catch" para o tipo de exceção lançada uma função global de tratamento de exceções invocadas é chamada(geralmente esta aborta a execução do programa). O exemplo a seguir ilustra:

#include
void* malloc(size_t);

struct my_out_of_memory
{
my_out_of_memory(size_t size)
{
this->size=size;
}//end myoutofsize
size_t size;
};

void* my_alloc(size_t size)
{

void* ptr=malloc(size);

if(ptr==NULL)
{
throw my_out_of_memory(size);
}//endif

return ptr;

}//end voidmyalloc

void q()
{

void* b1=NULL;
void* b2=NULL;
void* b3=NULL;

try
{
void* b1= my_malloc(1000);
void* b2= my_malloc(3000);
void* b3= my_malloc(4000);
//faça ago
}//end try

catch(my_out_of_memory& e)
{
printf("out of memory(%d bytes)\n", e.size);
}//end catch

free(b1);
free(b2);
free(b3);

}//end voidq

quinta-feira, julho 27, 2006

Vou tentar colocar todas as aulas!

Olá pessoal, o intuito desse blog é deixar disponível todas as aulas de prog 3.
Essa aula1, eu peguei do Hugo, e segundo ele em algum lugar há um ou dois erros, então se alguém ver o erro ae e poder falar, agradeço!
Outra coisa, caso queiram ajudar(um dia ajudando, outro dia sendo ajudado) mande a aula que copiou no meu e-mail jamildagher@gmail.com , assim caso eu não copie algum dia, teremos a aula sem problemas!

Espero que sirva pra alguma coisa!

\o/

Aula 1

AULA 01

Um objeto é uma coleção de atributos e/ou uma coleção de métodos.

->Os atributos de um objeto representam sua estrutura.
->Os métodos de um objeto acessão seus atributos e representam o comportamento do objeto.

Uma classe é a descrição de todos os stributos e todos os métodos de um determinado tipo de objeto.

Um objeto é uma instância de uma classe. Um objeto de uma classe conterá durante toda sua vida os atributos e métodos descritos na classe.

Uma mensagem é uma solicitação feita à um objeto para que este execute uma das operações definidas nba classe do objeto.

->Genéricamente o formato de uma mensagem é x.m(args), onde x é uma referência ao objeto receptor da mensagem; m é o seletor da mensagem; args é a lista(possívelmente vazia ) de argumentos da mensagem.
->O obejeto referanciado por x invocando o método m, definida em sua classe, cujos parâmetro casam em numero e tipo com os argumentos da mensagem. Este mecanismo é denominado aclopamento mensagem-método.
->Em programção orientada à objetos a computação ocorre em um universo contituido de objetos que trocam mensagens entre si, dentro deste universo objetos são criados, possuem um tempo de vida ultíl e são destruuidos dentro da computação.


Construção e Destruição de Objetos em C++

Seja a classe X:

struct X
{
int a;
void m(int);
};

Objetos em C++ podem ser criados: estática e dinamicamente.

Criar um objeto significa:
1) alocar memória para armazenamento dos atributos do objeto(declarados em sua classe) e, em determinados casos, imformações sobre os tipos dos objetos.
2)executar operações responsáveis pela inicialização dos odjetos(atribuir valores iniciais a atributos, enviar mensagens a outros objetos, alocar memória para uso interno, abrir arquivos,etc). Essas operações são definidas em métodos especias da classe do objeto chamados construtores.

Para criar estáticamente um objeto da classe X basta declarar:

X x;

A área de memória ocupada pelo objeto x é alocada estáticamente no segmento de dados(se a declarção for global) ou no segmento de pilha(se a declaração for local).
No primeiro caso o tempo de vida do objeto é igual ao tempo de vida do programa e seu escopo é global. No segundo caso o tempo de vida e o escopo são restritos ao bloco(tudo q começa{}) do objeto instanciado.
Alocada a memória para o objeto um método construtor deve ser invocado para sua inicialização, poprém na classe x nenhum construtor é declarado. Neste e somente neste caso o compilador provê um construtor automaticamente. Este não possui tipo de retorno, e tem nome identico ao da classe(aliás como todos os construtores em C++) e não possui parâmetros. Este construtor e chamado "default". O construtor default provido pelo compilador no caso da classe X não faz nada. É como se tivessemos declarado uma classe:

struct X
{
X(){};
int a;
void m(int);
};



Um outro tipo de contrutor em C++ é chamado construtor especial, este toma como argumento uma referência constante para um objeto da própria classe:

struct X

{

...

X (const X&);

...

}

Um construtor de cópia deve implementar a semântica de cópia para os objetos da classe. Se nenhum construtor de cópia é declarado, o compilador sempre provê um, cuja semântica de cópia é "shallow_copy"(cópia rasa), isto é, uma cópia membro a membro dos atributos do argumento passado ao contrutor para os atributos do objeto sendo construído.

Obs. Cópia rasa só é distinta de cópia profunda("deep_copy") para variáveis do tipo ponteiro ou referência. Seja então o ponteiro

X* p;

Uma cópia rasa de 'p' é um endereço cujo valor é o mesmo endereço de 'p', ou seja, uma cópia rasa de 'p' aponta para o mesmo objeto que 'p' aponta. Uma cópia profunda de 'p' é um endereço que aponta para uma cópia do objeto para o qual 'p' aponta, ou seja, 'p' e sua cópia profunda apontam para dois objetos idênticos.

Um objeto criado estáticamente é destruido automaticamente pelo programa quando seu escopo termina. A destruição de um objeto envolve:

1)Executar operações de finalização do objeto(liberação de memória para uso interno, fechamento de arquivos, etc, isto é,limpeza da cas). Essas operações são codificadas em um método especial definido na classe do objeto, chamado destrutor. Se o destrutor não é declarado o compilador provê.
2)Liberação da memória ocupada pelo objeto.

 
Design by Free WordPress Themes | Bloggerized by Lasantha - Premium Blogger Themes | Justin Bieber, Gold Price in India