Você está na página 1de 37

Introdução à Linguagem C++

IFPE – Tecnologia em Análise de


Desenvolvimento de Sistemas
Professor: Marcos Costa
Roteiro

 C++

 Classes e objetos
Construtores, funções membro, membros
de dados
 Interfaces
 Destrutores
Primeiro Exemplo em C++
class Person {

public:
string getFirstName() {
return firstName;
}
void setFirstName(string firstName) {
this->firstName = firstName;
}

//Obs: as funções membro setLastName e getLastName são análogas

private:
string firstName;
string lastName;
};
Primeiro Exemplo em C++
 Um membro público pode ser acessado por
qualquer código
 Os nomes de funções membro que iniciam com
get e set são convensões
 this é um ponteiro para o próprio objeto
instanciado
public:
string getFirstName() {
return firstName;
}
void setFirstName(string firstName) {
this->firstName = firstName;
}
Primeiro Exemplo em C++
 Ummembro privado só pode ser acessado por
membros da própria classe

 Encapsulamento
O membro de dado firstName só pode ser
acessado/modificado a partir das funções
membro get e set correspondentes

private:
string firstName;
string lastName;
Primeiro Exemplo em C++
 Se forem adicionadas regras de negócio para o
firstName, os clientes não precisarão ser
alterados
/*
* Só aceita nomes não vazios.
* Observe que utilizamos a função membro empty, definida na
* classe string
*/
void setFirstName(string firstName) {
if (!firstName.empty()) {
this->firstName = firstName;
}
}
Primeiro Exemplo em C++
 No início do arquivo cpp podemos
adicionar uma ou mais inclusões
#include <iostream> //entrada e saída
using std::cin;
using std::cout;
using std::endl;

#include <string> //classe string padrão de C++


using std::string;

class Person...
Primeiro Exemplo em C++
# é um sinal para o pré-processador
 O pré-processador tem como função ler o código
fonte à procura de linhas que comecem com o
símbolo # e modificar o código de acordo com a
instrução
 using std::cin
 Std é o namespace da biblioteca iostream – define
o escopo a qual identificadores e variáveis
pertencem
 Using permite que usemos cin sem a necessidade
de sempre especificar o escopo (std::cin)
Primeiro Exemplo em C++
int main() {
Person person1; //O objeto person1 é instanciado automaticamente
string firstName, lastName;

cout << "First name: "; //standard output (<< é o operador de inserção)
cin >> firstName; //standard input (>> é o operador de extração)
cout << "Last name: ";
cin >> lastName;

person1.setFirstName(firstName);
person1.setLastName(lastName);

cout << "Hello, " << person1.getFirstName() << " ";


cout << person1.getLastName() << endl;
return 0;
}
Primeiro Exemplo em C++

 Se não foi escrito nenhum construtor


 C++ assume a existência de um construtor
vazio
 Construtores são chamados no momento
da instanciação dos objetos
 Tipicamente são utilizados para iniciar os
valores dos membros de dados dos objetos
 Na instanciação, todo o espaço de memória
necessário ao objeto é alocado
Primeiro Exemplo em C++
 Declarando construtores explicitamente
class Person {
Public:
Person() {}

Person(string firstName, string lastName) {


setFirstName(firstName);
setLastName(lastName);
}
};

 Invocandoconstrutores com parâmetros


 Person person1(“João”,“Silva”);
Primeiro Exemplo em C++

 Sobrecarga
 Ocorrequando há duas ou mais funções
membro com o mesmo nome e cada uma
com diferentes tipos argumentos
 Um exemplo do uso de sobrecarga
 Pode ser visto nos dois contrutores da
classe “Person”
Exercício

 Precisamos adicionar mais três


membros de dados, correspondentes ao
dia, mês e ano de nascimento
 Alterar
construtor e adicionar funções
membro
private:
string firstName;
string lastName;
int birthMonth;
int birthDay;
int birthYear;
Esta Solução é Boa?

 Será que dia, mês e ano de nascimento


 Não são melhores representados por uma
data?
 Não poderíamos criar a classe data e a
pessoa ter um atributo data de nascimento?
private:
string firstName;
string lastName;
Date birthDate;
Criação da Classe Date
class Date { class Person {
/* public:
* Funções membro Person(string firstName, string lastName,
* omitidas Date birthDate) {
*/ setFirstName(firstName);
private: setLastName(lastName);
int month; setBirthDate(birthDate);
int year; }
int day;
}; private:
string firstName;
string lastName;
Date birthDate;
};
Criação da Classe Date

 Melhora a coesão e a reusabilidade


A classe Date pode conter funções membro
para manipulação e validação de datas
 Comparação de datas, validação de meses do
ano, etc.
A manutenção do código fica mais fácil
A classe Date pode ser utilizada por outras
classes além da classe Person
Classes em arquivos separados

 Classespodem ser criadas em


arquivos .h
 Os arquivos de cabeçalho podem ser
incluídos em outras classes ou no main
 Reusabilidade

/*
* Inclusão de arquivo .h que contém a definição
* da classe Person
*/
#include “person.h”
Separando Interface de
Implementação

A interface de uma classe descreve que


serviços um cliente pode utilizar
 Mas não a maneira como a classe executa
esses serviços
A interface de uma classe consiste de suas
funções membro public
Separando Interface de
Implementação

 Paraseparar interface de
implementação criamos dois arquivos
 Um “.h” para interface e um “.cpp” para a
implementação
Interface - circle.h
#ifndef _CIRCLE_H //Não podemos definir uma classe mais de uma vez
#define _CIRCLE_H
//Observe que as funções membro são apenas declaradas

namespace circle { //Observe a definição do namespace “circle”


class Circle {
public:
Circle(double); //Construtor recebe um double (o valor do raio)
double diameter();
double area();
double getRadius();
void setRadius(double);
static const double PI = 3.1415; //PI é uma constante estática
private:
double _radius;
};
}
#endif
Membros de Dados Estáticos

 São membros da classe e não das


instâncias
 Não é preciso instanciar um objeto para
utilizá-los
 Podem ser variáveis ou constantes

A palavra reservada const é utilizada


para constantes
Implementação - circle.cpp
#include <cmath> //o include referente a cout foi omitido
#include "circle.h"
using circle::Circle;
#define DEBUG 1 //Uma dica simples para debug de código

Circle::Circle(double radius) : radius(radius) {


#if DEBUG
cout << "Circle constructor: " << radius << endl;
#endif
} //As funções membro getRadius e setRadius foram omitidas

double Circle::area() {
return Circle::PI * pow(radius, 2);
}

double Circle::diameter() {
return 2 * radius;
}
Implementação
O operador “::” é chamado operador
unário de escopo
 Utilizando “::” na implementação faz com
que ela tenha acesso ao escopo da classe
 Toda implementação de função membro da
classe deve obrigatoriamente utilizá-lo
 Ele torna possível o acesso aos membros
de dados e funções membros, públicas ou
privadas
Implementação - circle.cpp
 Os dois contrutores abaixo são
equivalentes
 Em ambos, o membro de dado radius
recebe o valor de “radius”
/*
* Após os “:” podemos apenas fazer atribuições
* aos membros de dados. Dizemos que o corpo
* do construtor é vazio
*/
Circle::Circle(double radius) : radius(radius) { }

Circle::Circle(double radius) {
this->radius = radius;
}
Main Utilizando a Classe Circle

 setprecision
 Determina a precisão decimal na saída
 fixed e scientific
 Determinam o formato numérico da saída
#include <iostream>
using std::cout; using std::endl; using std::fixed; using std::scientific;

#include <iomanip>
using std::setprecision;

#include "circle.h"
using circle::Circle;
Main Utilizando a Classe Circle
int main() {
//Cria uma instância de Circle com raio 8.5
Circle circle(8.5);

cout << "PI: " << Circle::PI << endl;


cout << "Radius: " << circle.getRadius() << endl;
cout << "Area: " << setprecision(2) << fixed;
cout << circle.area() << endl;
cout << "Diameter: " << scientific;
cout << circle.diameter() << endl;
return 0;
}
E se a constante PI não for estática?

 Tornando a constante “pi” não estática


 Observe que o construtor de “Circle” agora
recebe o valor de pi como argumento
class Circle {
public:
Circle(double radius, double pi);
//O restante da interface permanece a mesma
private:
double radius;
const double pi;
};
E se a constante PI não for estática?

 Para cada instância de “Circle”, vai


existir um valor para o membro de dado
constante “pi”
E se a constante pi não for estática?

 Implementação do construtor
/*
* A atribuição do valor da constante de “pi” deverá ser
* obrigatoriamente após os “:”, antes do corpo do construtor
*/
Circle::Circle(double radius, double pi) : pi(pi), radius(radius) {
//this->radius = radius; a atribuição de radius poderia ser aqui
}

 Invocando o construtor
Circle circle(1.5, 3.14);
Destrutor C++

O destrutor pode ser visto como o


complemento do construtor
 Chamado automaticamente quando um
objeto é destruído
 Quando termina o escopo de existência do
objeto
Destrutor C++

 Tipicamenteutilizado para liberar


recursos associados ao objeto
 Pode-se dizer que o destrutor faz uma
faxina de terminação
 Mas o destrutor em si não libera a memória
do objeto
Destrutor C++

O destrutor não pode receber


parâmetros nem retornar valor
 Cada classe só pode possuir um único
destrutor
 Seo programador não escrever um
destrutor para uma classe
O compilador C++ cria automaticamente um
destrutor vazio
Destrutor C++

 Umdestrutor também pode ser


chamado explicitamente
 Mas isto só será visto em outro momento
Destrutor C++

 Interface
class Circle {
Public:
Circle(double radius, string name);
~Circle(); //Destrutor
string getName();
void setName(string);
...
private:
double radius;
string name;
}
Destrutor C++
 Implementação
Circle::Circle() (double radius, string name) :
class Circle { radius(radius), name(name) {
cout
public:<< "Circle constructor: ";
cout << getName();
~Circle();
cout << endl;
string getName();
} void setName(string);
...
Circle::~Circle()
private: {
cout << "Circle
double destructor: ";
_radius;
cout << getName();
string name;
cout
} << endl;
}
Destrutor C++
Circle globalCircle(1.0, “global circle”);

void func1() {
cout << "***** FUNC1: execution begins *****" << endl;
Circle localCircle(3.0, “automatic local func circle”);
static Circle staticLocalCircle(4.0, “static local func circle”);
cout << "***** FUNC1: execution ends *****" << endl;
}

int main() {
cout << "***** MAIN: execution begins *****" << endl;
Circle mainCircle(2.0, “automatic local main circle”);
func1(); //Observe que func1 é invocada duas vezes
func1();
cout << "***** MAIN: execution ends *****" << endl;
return 0;
}
Destrutor C++

'