Curso completo de linguagem C++
Gameprog - Escola de programação de jogos digitais
Contato: gameprog.br@gmail.com
track07.html

index << >>

07. Classes 1/5 - criando classes

7.1 Criandos classes
// criando_classes.cpp // ilustra a criacao de classes #include <iostream> using namespace std; // protótipo de nossas funções básicas void inicio(); void fim(); // Vamos criar uma classe Monstro para criar objetos monstro class Monstro { public: int m_energia; int m_estrago; Monstro () { m_energia = 100; m_estrago = 10; } void atacar() { cout << "\t Vc foi atacado e perdeu " << m_estrago << " pontos de energia. \n\n"; } }; // fim da classe monstro int main() { inicio(); int energia, estrago; // Criando um objeto da classe monstro Monstro godzila; // Obtendo valores das propriedades do objeto monstro energia = godzila.m_energia; estrago = godzila.m_estrago; cout << "\t m_energia: " << energia << "\n"; cout << "\t m_estrago: " << estrago << "\n"; // Vamos atacar godzila.atacar(); // Reconfigurando e mostrando as propriedades godzila.m_energia = 99; godzila.m_estrago = 999; cout << "\t m_energia: " << godzila.m_energia << "\n"; cout << "\t m_estrago: " << godzila.m_estrago << "\n"; godzila.atacar(); fim(); } // endmain //************* funções ****************************************************** void inicio() { system("color f0"); system("title criando classes"); cout << "\n"; } // endfunction: initsys() void fim() { cout << "\n"; system("pause"); } // endfunction: endsys()
No programa acima supomos que nossa necessidade é criar um jogo aonde vai haver monstros. Como propriedade básica esses monstros vão ter energia ( m_energia) que vai ser reduzida quando eles forem atacados pelo jogador. Esses monstros vão ser capazes da ação de atacar e terão a capacidade de causar estrago no jogador na extensão definida pela propriedade m_estrago. Então, esse é o contexto básico de nossa aplicação. Uma classe é criada dessa maneira: class Monstro { // bloco de código que define e implementa as propriedades e métodos }; Repare que deve haver um ponto e vírgula (;) no final da declaração da classe tal como ocorre também com a declaração de estruturas ( struct ). No miolo desse bloco você vai colocar no mínimo a definição das propriedades e dos métodos. public: int m_energia; int m_estrago; Com esta sintaxe acima vc define as propriedades da classe. A palavra chave public define que as propriedades e métodos vão ser públicos, isto é, as funções e propriedades vão poder ser acessadas e modificadas globalmente, dentro de qualquer lugar do nosso programa. É recomendável prefixar as propriedades com um m_ de membro. void atacar() { cout << "\t Vc foi atacado e perdeu " << m_estrago << " pontos de energia. \n\n"; } Vc pode definir e implementar dentro do bloco da classe as suas funções membros ou os métodos na terminologia de programação orientada a objetos. Como os métodos são apenas funções dentro de uma classe vc pode aplicar tudo que vc sabe sobre funções como sobrecarregá-los (overload), criar valores default, retornar valores etc. Monstro () { m_energia = 100; m_estrago = 10; } As classes possuem alguns métodos especiais. O método acima é denominado construtor e é chamado automaticamente na criação de um objeto. O construtor é usado para realizar processos de inicialização de objetos tal como definir os valores iniciais das propriedades. O construtor deve ter o mesmo nome da classe e não deve ter valores de retorno nem mesmo void. 7.1.1 Variações da sintaxe de criação de classes
// criando_classes_ver02.cpp // ilustra a criacao de classes com sintaxe alternativa #include <iostream> #include <string> using namespace std; // protótipo de nossas funções básicas void inicio(); void fim(); // Vamos criar uma classe Monstro para criar objetos monstro class Monstro { private: int m_energia; int m_estrago; string m_snome; public: Monstro (); Monstro (int energia, int estrago); Monstro (int energia, int estrago, string nome); void atacar(); string getName(); void setName(string nome); void info(); }; // endclass: Monstro int main() { inicio(); int energia, estrago; // Criando um objeto da classe monstro Monstro godzila; Monstro vampiro = Monstro (22,222); Monstro ogro = Monstro(33,333, "monstro_c3"); cout << "\n"; godzila.info(); ogro.info(); vampiro.info(); cout << "\n"; // Vamos atacar godzila.atacar(); vampiro.atacar(); ogro.atacar(); vampiro.setName("Dracula"); cout << "\n\tvampiro.getName(): " << vampiro.getName() << "\n"; vampiro.info(); // int Mosntro::m_energia is private within this context // vampiro.m_energia = 100; fim(); } // endmain //************* implementacao dos metodos ************************************ Monstro::Monstro() { cout << "\t Construtor 01 chamado" << "\n"; m_energia = 11; m_estrago = 111; m_snome = "monstro_c1"; } // fim do construtor 01 Monstro::Monstro(int energia, int estrago): m_energia(energia), m_estrago(estrago), m_snome("monstro_c2") {} // fim do construtor 02 Monstro::Monstro(int energia, int estrago, string nome): m_energia(energia), m_estrago(estrago), m_snome(nome) { cout << "\t Construtor 03 chamado" << "\n"; } // fim do construtor 03 void Monstro::atacar() { cout << "\t" << m_snome << " atacou e vc perdeu " << m_estrago << " pontos de energia. \n"; } // endmethod: atacar() string Monstro::getName() { return m_snome; } void Monstro::setName( string nome) { m_snome = nome; } void Monstro::info() { cout << "\t" << m_snome; cout << "\t energia: " << m_energia; cout << "\t estrago: " << m_estrago << "\n"; } // endmethod: info() //************* funcoes ****************************************************** void inicio() { system("color f0"); system("title criando classes versao 02"); cout << "\n"; } // endfunction: initsys() void fim() { cout << "\n"; system("pause"); } // endfunction: endsys()
private: int m_energia; int m_estrago; string m_snome; A instrução private determina que os membros da classe (propriedades e métodos) serão particulares da classe e não poderão ser acessados fora dela. Por exemplo, se vc tentar acessar m_energia tal como vampiro.m_energia = 100; o seu programa não compila e gera o seguinte erro int Monstro::m_energia is private within this context que bem traduzido fica int Monstro::m_energia é particular e portanto não pode ser acessada nesse contexto (main()). public: Monstro (); Monstro (int energia, int estrago); Monstro (int energia, int estrago, string nome); Aqui definimos que o construtor e os métodos serão públicos. Veja que sobrecarregamos o construtor permitindo que um objeto da classe seja criado e inicializado de diversas maneiras. void atacar(); string getName(); void setName(string nome); void info(); Os métodos normais são definidos como públicos e as propriedades privadas serão acessadas indiretamente por esses métodos. Esse estilo de acesso às propriedades é recomendado pelos melhores profissionais de programação, e as funções que dão acesso e manipulam indiretamente as propriedades são denominadas acessors em inglês, traduzindo ficaria como acessadoras. Quando uma função acessadora configura uma propriedade ela é uma função set (configurar) e quando ela obtém o valor de uma propriedade é uma função get (obter). void info(); // dentro do bloco da classe void Monstro::info() { // bloco de código } Na classe vc define os protótipos dos métodos. Na implementação dos métodos fora do bloco da classe vc deve prefixar o nome do método com o nome da classe usando o operador de resolução de escopo ( :: ) denominado em inglês scope resolution operator: tipo_retorno nome_da_classe::nome_do_método (tipo_dado, tipo_dado);. // Monstro godzila; Monstro::Monstro() { cout << "\t Construtor 01 chamado" << "\n"; m_energia = 11; m_estrago = 111; m_snome = "monstro_c1"; } // fim do construtor 01 Nesse primeiro construtor inicializamos as propriedades e emitimos uma mensagem via cout apenas para vc perceber que o construtor é chamado automaticamente na construção de um objeto. Com esse construtor vc cria um objeto dessa maneira: Monstro godzila; Monstro::Monstro(int energia, int estrago): m_energia(energia), m_estrago(estrago), m_snome("monstro_c2") {} O código acima representa uma maneira sucinta de inicializar as propriedades pelo construtor. É passado após a definição do construtor uma lista de inicialização de propriedades na forma: construtor(v1, v2): p1(v1), p2(v2) {}. Repare que fechamos as chaves sem a necessidade de adicionar outro código de inicialização. Com esse construtor vc cria um objeto dessa maneira: Monstro ogro = Monstro(33,333, "monstro_c3"); // Vamos atacar godzila.atacar(); vampiro.atacar(); ogro.atacar(); Veja que você ganha facilidades e produtividade com o uso de classes e objetos. Você poderia definir uma array de monstros e depois fazê-los atacar() de uma só vez usando uma estrutura for: Monstro bando[10]; for (int ncx = 0; ncx < 1; ncx++) bando[ncx].atacar();
index << >>


Produzido por Gameprog: Jair Pereira - Fev/2006 - Junho/2013 © gameprog.br@gmail.com http://www.gameprog.com.br