summaryrefslogtreecommitdiffhomepage
path: root/pt-br/c++-pt.html.markdown
blob: 243627cb24f6aeaff1d6fa5afe12f51d7948ed80 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
---
language: c++
filename: learncpp.cpp
contributors:
    - ["Steven Basart", "http://github.com/xksteven"]
    - ["Matt Kline", "https://github.com/mrkline"]
translators:
    - ["Miguel Araújo", "https://github.com/miguelarauj1o"]
lang: pt-br
---

C++ é uma linguagem de programação de sistemas que, 
C++ is a systems programming language that,
[de acordo com seu inventor Bjarne Stroustrup](http://channel9.msdn.com/Events/Lang-NEXT/Lang-NEXT-2014/Keynote),
foi concebida para

- ser um "C melhor"
- suportar abstração de dados
- suportar programação orientada a objetos
- suportar programação genérica

Embora sua sintaxe pode ser mais difícil ou complexa do que as linguagens mais
recentes, C++ é amplamente utilizado porque compila para instruções nativas que 
podem ser executadas diretamente pelo processador e oferece um controlo rígido sobre hardware (como C), enquanto oferece recursos de alto nível, como os 
genéricos, exceções e classes. Esta combinação de velocidade e funcionalidade 
faz C++ uma das linguagens de programação mais utilizadas.

```c++
//////////////////
// Comparação com C
//////////////////

// C ++ é quase um super conjunto de C e compartilha sua sintaxe básica para
// declarações de variáveis, tipos primitivos, e funções. No entanto, C++ varia
// em algumas das seguintes maneiras:

// A função main() em C++ deve retornar um int, embora void main() é aceita 
// pela maioria dos compiladores (gcc, bumbum, etc.)
// Este valor serve como o status de saída do programa.
// Veja http://en.wikipedia.org/wiki/Exit_status para mais informações.

int main(int argc, char** argv)
{
    // Argumentos de linha de comando são passados em pelo argc e argv da mesma
    // forma que eles estão em C.
    // argc indica o número de argumentos,
    // e argv é um array de strings, feito C (char*) representado os argumentos
    // O primeiro argumento é o nome pelo qual o programa foi chamado.
    // argc e argv pode ser omitido se você não se importa com argumentos,
    // dando a assinatura da função de int main()

    // Uma saída de status de 0 indica sucesso.
    return 0;
}

// Em C++, caracteres literais são um byte.
sizeof('c') == 1

// Em C, caracteres literais são do mesmo tamanho que ints.
sizeof('c') == sizeof(10)

// C++ tem prototipagem estrita
void func(); // função que não aceita argumentos

// Em C
void func(); // função que pode aceitar qualquer número de argumentos

// Use nullptr em vez de NULL em C++
int* ip = nullptr;

// Cabeçalhos padrão C estão disponíveis em C++,
// mas são prefixados com "c" e não têm sufixo .h

#include <cstdio>

int main()
{
    printf("Hello, world!\n");
    return 0;
}

///////////////////////
// Sobrecarga de função
///////////////////////

// C++ suporta sobrecarga de função
// desde que cada função tenha parâmetros diferentes.

void print(char const* myString)
{
    printf("String %s\n", myString);
}

void print(int myInt)
{
    printf("My int is %d", myInt);
}

int main()
{
    print("Hello"); // Funciona para void print(const char*)
    print(15); // Funciona para void print(int)
}

/////////////////////////////
// Parâmetros padrão de função
/////////////////////////////

// Você pode fornecer argumentos padrões para uma função se eles não são 
// fornecidos pelo chamador.

void doSomethingWithInts(int a = 1, int b = 4)
{
    // Faça alguma coisa com os ints aqui
}

int main()
{
    doSomethingWithInts();      // a = 1,  b = 4
    doSomethingWithInts(20);    // a = 20, b = 4
    doSomethingWithInts(20, 5); // a = 20, b = 5
}

// Argumentos padrões devem estar no final da lista de argumentos.

void invalidDeclaration(int a = 1, int b) // Erro!
{
}


/////////////
// Namespaces (nome de espaços)
/////////////

// Namespaces fornecem escopos distintos para variável, função e outras
// declarações. Namespaces podem estar aninhados.

namespace First {
    namespace Nested {
        void foo()
        {
            printf("This is First::Nested::foo\n");
        }
    } // Fim do namespace aninhado
} // Fim do namespace First

namespace Second {
    void foo()
    {
        printf("This is Second::foo\n")
    }
}

void foo()
{
    printf("This is global foo\n");
}

int main()
{
    // Assuma que tudo é do namespace "Second" a menos que especificado de 
    // outra forma.
    using namespace Second;

    foo(); // imprime "This is Second::foo"
    First::Nested::foo(); // imprime "This is First::Nested::foo"
    ::foo(); // imprime "This is global foo"
}

///////////////
// Entrada/Saída
///////////////

// C ++ usa a entrada e saída de fluxos (streams)
// cin, cout, and cerr representa stdin, stdout, and stderr.
// << É o operador de inserção e >> é o operador de extração.

#include <iostream> // Inclusão para o I/O streams

using namespace std; // Streams estão no namespace std (biblioteca padrão)

int main()
{
   int myInt;

   // Imprime na saída padrão (ou terminal/tela)
   cout << "Enter your favorite number:\n";
   // Pega a entrada
   cin >> myInt;

   // cout também pode ser formatado
   cout << "Your favorite number is " << myInt << "\n";
   // imprime "Your favorite number is <myInt>"

    cerr << "Usado para mensagens de erro";
}

//////////
// Strings
//////////

// Strings em C++ são objetos e têm muitas funções de membro
#include <string>

using namespace std; // Strings também estão no namespace std (bib. padrão)

string myString = "Hello";
string myOtherString = " World";

// + é usado para concatenação.
cout << myString + myOtherString; // "Hello World"

cout << myString + " You"; // "Hello You"

// Em C++, strings são mutáveis e têm valores semânticos.
myString.append(" Dog");
cout << myString; // "Hello Dog"


/////////////
// Referência
/////////////

// Além de indicadores como os de C, C++ têm _referências_. Esses são tipos de
// ponteiro que não pode ser reatribuída uma vez definidos e não pode ser nulo.
// Eles também têm a mesma sintaxe que a própria variável: Não * é necessário 
// para _dereferencing_ e & (endereço de) não é usado para atribuição.

using namespace std;

string foo = "I am foo";
string bar = "I am bar";


string& fooRef = foo; // Isso cria uma referência para foo.
fooRef += ". Hi!"; // Modifica foo através da referência
cout << fooRef; // Imprime "I am foo. Hi!"

// Não realocar "fooRef". Este é o mesmo que "foo = bar", e foo == "I am bar"
// depois desta linha.

fooRef = bar;

const string& barRef = bar; // Cria uma referência const para bar.
// Como C, valores const (e ponteiros e referências) não podem ser modificado.
barRef += ". Hi!"; // Erro, referência const não pode ser modificada.

//////////////////////////////////////////
// Classes e programação orientada a objeto
//////////////////////////////////////////

// Primeiro exemplo de classes
#include <iostream>

// Declara a classe.
// As classes são geralmente declarado no cabeçalho arquivos (.h ou .hpp).
class Dog {
    // Variáveis de membro e funções são privadas por padrão.
    std::string name;
    int weight;

// Todos os membros a seguir este são públicos até que "private:" ou 
// "protected:" é encontrado.
public:

    // Construtor padrão
    Dog();

    // Declarações de função Membro (implementações a seguir)
    // Note que usamos std :: string aqui em vez de colocar
    // using namespace std;
    // acima.
    // Nunca coloque uma declaração "using namespace" em um cabeçalho.
    void setName(const std::string& dogsName);

    void setWeight(int dogsWeight);

    // Funções que não modificam o estado do objecto devem ser marcadas como 
    // const. Isso permite que você chamá-los se for dada uma referência const
    // para o objeto. Além disso, observe as funções devem ser explicitamente
    // declarados como _virtual_, a fim de ser substituídas em classes 
    // derivadas. As funções não são virtuais por padrão por razões de 
    // performance.
    
    virtual void print() const;

    // As funções também podem ser definidas no interior do corpo da classe.
    // Funções definidas como tal são automaticamente embutidas.
    void bark() const { std::cout << name << " barks!\n" }

    // Junto com os construtores, C++ fornece destruidores.
    // Estes são chamados quando um objeto é excluído ou fica fora do escopo.
    // Isto permite paradigmas poderosos, como RAII
    // (veja abaixo)
    // Destruidores devem ser virtual para permitir que as classes de ser 
    // derivada desta.
    virtual ~Dog();

}; // Um ponto e vírgula deve seguir a definição de classe.

// Funções membro da classe geralmente são implementados em arquivos .cpp.
void Dog::Dog()
{
    std::cout << "A dog has been constructed\n";
}

// Objetos (como strings) devem ser passados por referência
// se você está modificando-os ou referência const se você não é.
void Dog::setName(const std::string& dogsName)
{
    name = dogsName;
}

void Dog::setWeight(int dogsWeight)
{
    weight = dogsWeight;
}

// Observe que "virtual" só é necessária na declaração, não a definição.
void Dog::print() const
{
    std::cout << "Dog is " << name << " and weighs " << weight << "kg\n";
}

void Dog::~Dog()
{
    cout << "Goodbye " << name << "\n";
}

int main() {
    Dog myDog; // imprime "A dog has been constructed"
    myDog.setName("Barkley");
    myDog.setWeight(10);
    myDog.printDog(); // imprime "Dog is Barkley and weighs 10 kg"
    return 0;
} // imprime "Goodbye Barkley"

// herança:

// Essa classe herda tudo público e protegido da classe Dog
class OwnedDog : public Dog {

    void setOwner(const std::string& dogsOwner)

    // Substituir o comportamento da função de impressão de todas OwnedDogs.
    // Ver http://en.wikipedia.org/wiki/Polymorphism_(computer_science)#Subtyping
    // Para uma introdução mais geral, se você não estiver familiarizado com o 
    // polimorfismo subtipo. A palavra-chave override é opcional, mas torna-se 
    // na verdade você está substituindo o método em uma classe base.
    void print() const override;

private:
    std::string owner;
};

// Enquanto isso, no arquivo .cpp correspondente:

void OwnedDog::setOwner(const std::string& dogsOwner)
{
    owner = dogsOwner;
}

void OwnedDog::print() const
{
    Dog::print(); // Chame a função de impressão na classe Dog base de
    std::cout << "Dog is owned by " << owner << "\n";
    // Prints "Dog is <name> and weights <weight>"
    //        "Dog is owned by <owner>"
}

//////////////////////////////////////////
// Inicialização e Sobrecarga de Operadores
//////////////////////////////////////////

// Em C ++, você pode sobrecarregar o comportamento dos operadores, tais como 
// +, -, *, /, etc. Isto é feito através da definição de uma função que é 
// chamado sempre que o operador é usado.

#include <iostream>
using namespace std;

class Point {
public:
    // Variáveis membro pode ser dado valores padrão desta maneira.
    double x = 0;
    double y = 0;

    // Define um construtor padrão que não faz nada
    // mas inicializar o Point para o valor padrão (0, 0)
    Point() { };

    // A sintaxe a seguir é conhecido como uma lista de inicialização
    // e é a maneira correta de inicializar os valores de membro de classe
    Point (double a, double b) :
        x(a),
        y(b)
    { /* Não fazer nada, exceto inicializar os valores */ }

    // Sobrecarrega o operador +.
    Point operator+(const Point& rhs) const;

    // Sobrecarregar o operador +=.
    Point& operator+=(const Point& rhs);

    // Ele também faria sentido para adicionar os operadores - e -=,
    // mas vamos pular para sermos breves.
};

Point Point::operator+(const Point& rhs) const
{
    // Criar um novo ponto que é a soma de um e rhs.
    return Point(x + rhs.x, y + rhs.y);
}

Point& Point::operator+=(const Point& rhs)
{
    x += rhs.x;
    y += rhs.y;
    return *this;
}

int main () {
    Point up (0,1);
    Point right (1,0);
    // Isto chama que o operador ponto +
    // Ressalte-se a chamadas (função)+ com direito como seu parâmetro...
    Point result = up + right;
    // Imprime "Result is upright (1,1)"
    cout << "Result is upright (" << result.x << ',' << result.y << ")\n";
    return 0;
}

/////////////////////////
// Tratamento de Exceções
/////////////////////////

// A biblioteca padrão fornece alguns tipos de exceção
// (see http://en.cppreference.com/w/cpp/error/exception)
// mas qualquer tipo pode ser jogado como uma exceção
#include <exception>

// Todas as exceções lançadas dentro do bloco try pode ser capturado por 
// manipuladores de captura subseqüentes
try {
    // Não aloca exceções no heap usando _new_.
    throw std::exception("A problem occurred");
}
// Capturar exceções por referência const se eles são objetos
catch (const std::exception& ex)
{
  std::cout << ex.what();
// Captura qualquer exceção não capturada pelos blocos _catch_ anteriores
} catch (...)
{
    std::cout << "Exceção desconhecida encontrada";
    throw; // Re-lança a exceção
}

///////
// RAII
///////

// RAII significa alocação de recursos é de inicialização.
// Muitas vezes, é considerado o paradigma mais poderoso em C++, e é o 
// conceito simples que um construtor para um objeto adquire recursos daquele
// objeto e o destruidor liberá-los.

// Para entender como isso é útil,
// Considere uma função que usa um identificador de arquivo C:
void doSomethingWithAFile(const char* filename)
{
    // Para começar, assuma que nada pode falhar.

    FILE* fh = fopen(filename, "r"); // Abra o arquivo em modo de leitura.

    doSomethingWithTheFile(fh);
    doSomethingElseWithIt(fh);

    fclose(fh); // Feche o arquivo.
}

// Infelizmente, as coisas são levemente complicadas para tratamento de erros.
// Suponha que fopen pode falhar, e que doSomethingWithTheFile e 
// doSomethingElseWithIt retornam códigos de erro se eles falharem. (As 
// exceções são a forma preferida de lidar com o fracasso, mas alguns 
// programadores, especialmente aqueles com um conhecimento em C, discordam 
// sobre a utilidade de exceções). Agora temos que verificar cada chamada para 
// o fracasso e fechar o identificador de arquivo se ocorreu um problema.

bool doSomethingWithAFile(const char* filename)
{
    FILE* fh = fopen(filename, "r"); // Abra o arquivo em modo de leitura
    if (fh == nullptr) // O ponteiro retornado é nulo em caso de falha.
        reuturn false; // Relate o fracasso para o chamador.

    // Suponha cada função retorne false, se falhar
    if (!doSomethingWithTheFile(fh)) {
        fclose(fh); // Feche o identificador de arquivo para que ele não vaze.
        return false; // Propague o erro.
    }
    if (!doSomethingElseWithIt(fh)) {
        fclose(fh); // Feche o identificador de arquivo para que ele não vaze.
        return false; // Propague o erro.
    }

    fclose(fh); // Feche o identificador de arquivo para que ele não vaze.
    return true; // Indica sucesso
}

// Programadores C frequentemente limpam isso um pouco usando Goto:
bool doSomethingWithAFile(const char* filename)
{
    FILE* fh = fopen(filename, "r");
    if (fh == nullptr)
        reuturn false;

    if (!doSomethingWithTheFile(fh))
        goto failure;

    if (!doSomethingElseWithIt(fh))
        goto failure;

    fclose(fh); // Close the file
    return true; // Indica sucesso

failure:
    fclose(fh);
    return false; // Propague o erro.
}

// Se as funções indicam erros usando exceções,
// as coisas são um pouco mais limpo, mas ainda abaixo do ideal.
void doSomethingWithAFile(const char* filename)
{
    FILE* fh = fopen(filename, "r"); // Abra o arquivo em modo de leitura.
    if (fh == nullptr)
        throw std::exception("Não pode abrir o arquivo.");

    try {
        doSomethingWithTheFile(fh);
        doSomethingElseWithIt(fh);
    }
    catch (...) {
        fclose(fh); // Certifique-se de fechar o arquivo se ocorrer um erro.
        throw; // Em seguida, re-lance a exceção.
    }

    fclose(fh); // Feche o arquivo
    // Tudo ocorreu com sucesso!
}

// Compare isso com o uso de C++ classe fluxo de arquivo (fstream) fstream usa
// seu destruidor para fechar o arquivo. Lembre-se de cima que destruidores são
// automaticamente chamado sempre que um objeto cai fora do âmbito.
void doSomethingWithAFile(const std::string& filename)
{
    // ifstream é curto para o fluxo de arquivo de entrada
    std::ifstream fh(filename); // Abra o arquivo

    // faça alguma coisa com o arquivo
    doSomethingWithTheFile(fh);
    doSomethingElseWithIt(fh);

} // O arquivo é automaticamente fechado aqui pelo destructor

// Isto tem _grandes_ vantagens:
// 1. Não importa o que aconteça,
//    o recurso (neste caso, o identificador de ficheiro) irá ser limpo.
//    Depois de escrever o destruidor corretamente,
//    É _impossível_ esquecer de fechar e vazar o recurso
// 2. Nota-se que o código é muito mais limpo.
//    As alças destructor fecham o arquivo por trás das cenas
//    sem que você precise se preocupar com isso.
// 3. O código é seguro de exceção.
//    Uma exceção pode ser jogado em qualquer lugar na função e a limpeza
//    irá ainda ocorrer.

// Todos códigos C++ usam RAII extensivamente para todos os recursos.
// Outros exemplos incluem
// - Memória usa unique_ptr e shared_ptr
// - Contentores - a lista da biblioteca ligada padrão,
//   vetor (i.e. array de autodimensionamento), mapas hash, e assim por diante
//   tudo é automaticamente destruído quando eles saem de escopo
// - Mutex usa lock_guard e unique_lock
```
Leitura Adicional:

Uma referência atualizada da linguagem pode ser encontrada em 
<http://cppreference.com/w/cpp>

Uma fonte adicional pode ser encontrada em <http://cplusplus.com>