C++: Programação Imperativa e Orientada a Objetos
Introdução
C++ é uma linguagem de programação orientada a objetos, de tipagem estática, de uso geral. Por vários anos, a linguagem evoluiu até o lançamento oficial em 1985. C++ é essencialmente uma extensão da linguagem de programação C, portanto muitas das coisas que você pode fazer em C você também pode fazer em C++. Ambas são amplamente compatíveis e, em muitos casos, o código C pode ser usado com pouca ou nenhuma modificação como código C++. Mas, além disso, o C++ fornece todo o poder e flexibilidade da orientação a objetos. Então você pode usar chamadas de sistema de baixo nível, gerenciar a memória e lidar com ponteiros, enquanto, ao mesmo tempo, trabalha com classes, objetos, herança e todos os recursos de uma linguagem orientada a objetos.
Executando Programas em C++
Para todos os programas em C++ deve-se utilizar um compilador cujo trabalho seja compilar o código C++ em código de máquina legível pelo computador. Utilizamos para tal o seguinte comando:
gcc -o nome_executavel arquivo.c
Tal linguagem depende do usuário para gerenciar a memória do programa, embora existam coletores de lixo disponíveis para C++. Muitos desenvolvedores optam por escrever C ++ usando um editor de texto básico, mas também há ambientes de desenvolvimento integrados mais especializados, alguns dos mais populares incluem Code Blocks , Eclipse e NetBeans.
Printando
cout << "Olá ";
cout << "Mundo ";
cout << "!" << endl;
Variáveis e Tipos de Dados
/*
Nomes são case-sensitive e devem começar com: letters, _
Depois, devem incluir: letters, numbers, _
A convenção diz:
"Comece com uma palavra começando com letra minúscula, então as palavras adicionais começam
com letra maiúscula."
Exemplo: minhaPrimeiraVariavel
*/
string nome = "Amintas"; // lista de caracteres (não primitivo)
char nota = 'A'; // caractere simples 8 bits
short idade0 = 10; // inteiro 16 bits com sinal
int idade1 = 20; // inteiro 16 bits com sinal (maior do que short)
long idade2 = 30; // inteiro 32 bits com sinal
long long idade3 = 40; // inteiro 64 bits com sinal
// para torná-los sem sinal, basta adicionar o prefixo "unsigned"
float media0 = 2.5f; // ponto flutuante de precisão simples
double media1 = 3.5; // ponto flutuante de precisão dupla
long double media2 = 3.5; // ponto flutuante de precisão extendida
bool ehAlto; // 1 bit -> true/false
ehAlto = true;
// podemos printar o valor de variáveis:
cout << "Meu nome é " << nome << endl;
Casting e conversão
cout << (int)3.14 << endl; // 3
cout << (double)3 / 2 << endl; // 1.5
Ponteiros
int num = 10;
cout << &num << endl; // referência de num
int *pNum = #
cout << pNum << endl; // referência de num
cout << *pNum << endl; // 10
Strings
#include <string> // importando biblioteca de strings
string palavra = "Olá";
// índices: 012
cout << palavra.length(); // tamanho da string (5)
cout << palavra[0] << endl; // char indexado ('')
cout << palavra.find("lá") << endl; // a partir de qual índice encontramos a substring (1)
cout << palavra.substr(1) << endl; // substring do índice até o final ("lá")
cout << palavra.substr(0, 1) << endl; // substring do primeiro índice ao segundo ("Ol")
Números
cout << 2 * 3 << endl; // aritmética básica: +, -, /, *
cout << 10 % 3 << endl; // módulo da divisão inteira
cout << 1 + 2 * 3 << endl; // ordem das operações: 1 + (2 * 3)
cout << 10 / 3.0 << endl; // ints operando com doubles = double
int n = 10;
num++; // += 1
n += 100; // +=, -=, /=, *=
#import <cmath> // importando funções matemáticas úteis
cout << pow(2, 3) << endl; // potenciação
cout << sqrt(144) << endl; // radiciação quadrada
cout << round(2.7) << endl; // arredondamento
Entrada do Usuário
string nome;
cout << "Insira seu nome: ";
cin >> nome; // entrada do usuário (string)
cout << "Olá " << nome << endl;
int num1, num2; // declarando múltiplas vaŕiáveis com mesmo tipo na mesma linha
cout << "Insira o primeiro número: ";
cin >> num1; // conversão implícita (string -> int)
cout << "Insira o segundo número: ";
cin >> num2;
cout << "Soma: " << num1 + num2 << endl;
Arrays
int numeros[6]; // array com 6 posições vazias
int numeros[] = {4, 8, 15, 16, 23, 42};
// índices: 0 1 2 3 4 5
cout << numeros[1] << endl; // podemos acessar valores através dos índices
numeros[0] = 90; // podemos editar valores através dos índices -> numeros[] = {90,8,15,16,23,42}
Arrays Bidimensionais
int matriz[2][3]; // matriz com 2 linhas e 3 colunas vazias
int matriz[2][3] = { {1, 2, 3}, {4, 5, 6} };
// 1 2 3
// 4 5 6
cout << matriz[0][0] << endl; // podemos acessar valores através dos índices
matriz[0][1] = 99; // podemos editar valores através dos índices -> matriz[2][3] = {{1,90,3},{4,5,6}}
Vetores
#include <vector> // importando biblioteca de vetores
vector<string> friends; // instanciando vetor de strings vazio
friends.push_back("Oscar"); // adicionando ao final
friends.push_back("Angela");
friends.insert(friends.begin() + 1, "Jim"); // inserindo elemento no índice 1
friends.erase(friends.begin() + 1); // excluindo elemento do índice 1
cout << friends.at(1) << endl; // acessando elemento do índice 1
cout << friends.size() << endl; // obtendo tamanho do vector
Funções
// assinatura do método antes de ser chamado no main
int addNumbers(int num1, int num2);
// main sempre retorna 0 (convenção)
int main()
{
int sum = addNumbers(4, 60);
cout << sum << endl;
return 0;
}
// implementação antes ou depois do main
int addNumbers(int num1, int num2){
return num1 + num2;
}
Condicionais
bool a = true;
bool b = false;
// podemos usar and(&&), or(||), ou not(!) nas expressões booleanas
if(a && b){
// ...
} else if(a || !b){
// ...
} else {
// ...
}
// podemos comparar números com >, <, >=, <=, != e == nas expressões booleanas
if(1 > 3){
// ...
} else if ('a' > 'b'){ // e o mesmo se aplica ao comparar caracteres
// ...
}
// comparamos strings com o método compare, que retorna 0 se as strings forem iguais
string s = "string";
if(s.compare("string") != 0){
// ...
}
Switch Case
char myGrade = 'A';
// dependo do valor da variável, um comportamento é tomado
switch(myGrade){
case 'A':
cout << "You Pass" << endl;
break;
case 'F':
cout << "You fail" << endl;
break;
default:
// o caso default funciona como um else
cout << "Invalid grade" << endl;
}
Loop Indefinido
int index = 1;
// não sabemos quantas iterações serão realizadas
// enquanto a condição for verdadeira, o comando é repitido
while (index <= 5) {
cout << index << endl;
index++;
}
// realiza o comando ao menos uma vez, verificando a condição depois
do{
cout << index << endl;
index++;
} while (index <= 5);
Loop Definido
// sabemos quantas iterações serão realizadas
for(int i = 0; i < 5; i++){
cout << i << endl;
}
Tratamento de Exceções
double division(int a, int b) {
if( b == 0 ) {
// ao lançar a exceção, a mensagem que passamos como parâmetro é mostrada
throw "Division by zero error!";
}
return (a/b);
}
int main(){
try {
division(10, 0);
} catch (const char* msg) {
cerr << msg << endl;
}
return 0;
}
Classes e Objetos
// criando uma classe, definindo um objeto
class Book{
public:
// definindo atributos inerentes
string title;
string author;
// definindo métodos inerentes
// quando nos referimos aos atributos, usamos: this->atributo
void readBook(){
cout << "Reading " + this->title + " by " + this->author << endl;
}
};
// podemos ter várias instâncias de um mesmo objeto
Book book1;
book1.title = "Harry Potter";
book1.author = "JK Rowling";
Book book2;
book2.title = "Lord of the Rings";
book2.author = "JRR Tolkien";
// usamos os métodos de forma independente
book2.readBook();
cout << book2.title << endl;
Construtores
class Book{
public:
string title;
string author;
// usamos construtores para criar instâncias de forma elegante
Book(string title, string author){
this->title = title;
this->author = author;
}
void readBook(){
cout << "Reading " + this->title + " by " + this->author << endl;
}
};
// criamos assim instâncias de forma muito mais legível e enxulta, garantindo bom design
Book book1("Harry Potter", "JK Rowling");
cout << book1.title << endl;
Book book2("Lord of the Rings", "JRR Tolkien");
cout << book2.title << endl;
Getters e Setters
class Book{
private:
string title;
string author;
public:
Book(string title, string author){
this->setTitle(title);
this->setAuthor(author);
}
// para acessar os atributos de um objeto, usamos métodos getters
// para alterar os atributos de um objeto, usamos métodos setters
string getTitle(){
return this->title;
}
void setTitle(string title){
this->title = title;
}
string getAuthor(){
return this->author;
}
void setAuthor(string author){
this->author = author;
}
void readBook(){
cout << "Reading " + this->title + " by " + this->author << endl;
}
};
Book book1("Harry Potter", "JK Rowling");
cout << book1.getTitle() << endl;
Book book2("Lord of the Rings", "JRR Tolkien");
book2.setTitle("LOTR: The Fellowship of the Ring");
Herança
class Chef{
public:
string name;
int age;
Chef(string name, int age){
this->name = name;
this->age = age;
}
void makeChicken(){
cout << "The chef makes chicken" << endl;
}
void makeSalad(){
cout << "The chef makes salad" << endl;
}
void makeSpecialDish(){
cout << "The chef makes a special dish" << endl;
}
};
// com herança, podemos criar objetos que herdam atributos e/ou métodos de outro
// sendo estes mais específicos
class EuropeanChef : public Chef{
public:
string countryOfOrigin;
// ao herdar atributos, estes são reaproveitados em construtores novos
// a partir dos construtores da superclasse
EuropeanChef(string name, int age, string countryOfOrigin) : Chef(name, age){
this->countryOfOrigin = countryOfOrigin;
}
// da mesma forma, novos atributos e métodos podem ser criados
void makePasta(){
cout << "The chef makes pasta" << endl;
}
// assim como métodos podem ser sobrescritos (override)
void makeSpecialDish(){
cout << "The chef makes chicken parm" << endl;
}
};
Chef myChef("Gordon Ramsay", 50);
myChef.makeChicken();
EuropeanChef myItalianChef("Massimo Bottura", 55, "Italy");
myItalianChef.makeChicken();
cout << myItalianChef.age << endl;
Classes e Métodos Abstratos
// com a palavra-chave "virtual", criamos classes abstratas, ou seja, que não podem ser instanciadas
virtual class Vehicle{
public:
// determinamos a assinatura de um método a ser instanciado com "virtual"
virtual void move() = 0;
void getDescription(){
cout << "Vehicles are used for transportation" << endl;
}
};
class Plane : public Vehicle{
public:
// implementamos o método cuja assinatura foi herdada
void move(){
cout << "The plane flys through the sky" << endl;
}
};
Plane myPlane;
myPlane.move(); // usamos o método implementado por Plane