Aprenda C++

  • Página Inicial
  • Contato!
  • Tudo sobre C++ Parte 1!
  • Tudo sobre C++ Parte 2!
  • Tudo sobre C++ Parte 3!
  • Tudo sobre C++ Parte 4!
  • Tudo sobre C++ Parte 5!
  • Tudo sobre C++ Parte 6!
  • Tudo sobre C++ Parte 7!
  • Tudo sobre C++ Parte 8!
  • Tudo sobre C++ Parte 9!
  • Tudo sobre C++ Parte 10!
  • Tudo sobre C++ Parte 11!
  • Tudo sobre C++ Parte 12!
  • Tudo sobre C++ Parte 13!
  • Tudo sobre C++ Parte 14!
  • Tudo sobre C++ Parte 15!
  • Tudo sobre C++ Parte 16!
  • Tudo sobre C++ Parte 16

    Data e Hora em C++ 11

    Podemos fazer dessa forma para manipular data e hora em C++ moderno (inclua as bibliotecas chrono e ctime):

    
    using namespace std;
    using namespace chrono;
    
    int main() {
        time_t atual = system_clock::to_time_t(system_clock::now()); // Exibe com ctime(&atual)
    
        string data(10, ' ');
        strftime(&data[0], data.size() + 1, "%d/%m/%Y", localtime(&atual));
    
        string hora(8, ' ');
        strftime(&hora[0], hora.size() + 1, "%H:%M:%S", localtime(&atual));
    
        string ds(1, ' ');
        strftime(&ds[0], ds.size() + 1, "%w", localtime(&atual));
    
        string semana[7] = {"Domingo", "Segunda-feira", "Terça-feira", "Quarta-feira", "Quinta-feira", "Sexta-feira", "Sábado"};
    
        cout << data << endl;
        cout << hora << endl;
        cout << semana[stoi(ds)] << endl;
    
        return 0;
    }
    
    

    Podemos até criar uma classe baseada no uso dessas bibliotecas (nesse caso inclua iostream, chrono e ctime no arquivo h):

    
    using namespace std;
    using namespace chrono;
    
    class Date {
        public:
            string now();
            string week();
            int day();
            int month();
            int year();
            int hours();
            int minutes();
            int seconds();
        private:
            static time_t atual;
            static string semana[7];
            int ds;
    
            string manip(int quant, const char* tex);
    };
    
    time_t Date::atual = system_clock::to_time_t(system_clock::now());
    string Date::semana[7] = {"Domingo", "Segunda-feira", "Terça-feira", "Quarta-feira", "Quinta-feira", "Sexta-feira", "Sábado"};
    
    string Date::now() {
        return ctime(&atual);
    }
    
    string Date::manip(int quant, const char* tex) {
        string data(quant, ' ');
        strftime(&data[0], data.size() + 1, tex, localtime(&atual));
    
        return data;
    }
    
    string Date::week() {
        ds = stoi(this->manip(1, "%w"));
    
        return semana[ds];
    }
    
    int Date::day() {
        return stoi(this->manip(2, "%d"));
    }
    
    int Date::month() {
        return stoi(this->manip(2, "%m"));
    }
    
    int Date::year() {
        return stoi(this->manip(4, "%Y"));
    }
    
    int Date::hours() {
        return stoi(this->manip(2, "%H"));
    }
    
    int Date::minutes() {
        return stoi(this->manip(2, "%M"));
    }
    
    int Date::seconds() {
        return stoi(this->manip(2, "%S"));
    }
    
    

    Dessa forma, podemos simplesmente chamar assim no programa principal (dê o include do arquivo Date.h):

    
    Date dataAtual;
    
    cout << "O dia da semana é: " << dataAtual.week() << endl;
    
    cout << "O dia de hoje é: ";
    cout << dataAtual.day() << "/" << dataAtual.month() << "/" << dataAtual.year() << endl;
    
    cout << "A hora atual é: ";
    cout << dataAtual.hours() << ":" << dataAtual.minutes() << ":" << dataAtual.seconds() << endl;
    
    

    Smart Pointer/Ponteiro Inteligente em C++ 11

    Os smart pointer, diferente dos ponteiros normais, ele destrói o elemento automaticamente após a execução ou alguma exceção, liberando memória automaticamente após o uso do objeto sem necessidade de usar free ou delete.

    Relembrando, um ponteiro em num, nós fazemos assim:

    
    int *pont; // Criação do ponteiro
    int num; // Variável do mesmo tipo
    
    num = 10; // Atribuição de valor à variável
    pont = &num; // Atribuição do endereço de num à variável
    
    cout << "Conteúdo..: " << *pont << endl; // Conteúdo de num
    cout << "Endereço..: " << pont << endl; // Endereço de num
    
    delete pont;
    
    

    Agora deixe o código assim, transformando o int num objeto:

    
    int *pont = new int();
    
    *pont = 10;
    
    cout << "Conteúdo..: " << *pont << endl; // Conteúdo de pont
    cout << "Endereço..: " << &pont << endl; // Endereço de pont
    
    delete pont;
    
    

    Mas até aí, nada de novo.

    Para usarmos os ponteiros inteligentes, importamos a biblioteca memory, veja um exemplo de alteração do código acima, dessa forma

    
    unique_ptr<int> pont(new int());
    
    *pont = 10;
    
    cout << "Conteúdo..: " << *pont << endl; // Conteúdo de pont
    cout << "Endereço..: " << &pont << endl; // Endereço de pont
    
    

    Como visto acima, não se usa o delete, e nem é necessário, porque ele já faz a coleta de lixo automaticamente.

    Só que tem um porém, o unique_ptr só permite um ponteiro por vez, portanto, isso não é possível fazer:

    
    unique_ptr<int> pont(new int());
    unique_ptr<int> pont2 = pont;
    
    

    Para resolver isso, usamos o ponteiro compartilhado, shared_ptr, dessa forma:

    
    shared_ptr<int> pont(new int());
    shared_ptr<int> pont2 = pont;
    
    

    Em outras palavras, o unique_ptr não pode ser compartilhado, já o shared_ptr permite isso, mas é menos usado. Temos também o auto_ptr, que identifica automaticamente, mas ele foi removido em versões mais recentes do C++ por desuso;

    Crie agora um ponteiro tradicional de objeto string, assim:

    
    string *pal = new string("Cursos");
    
    cout << "Palavra: " << *pal << endl;
    cout << "Tamanho: " << pal->size() << endl;
    
    

    O mesmo código usando o ponteiro inteligente:

    
    unique_ptr<string> pal(new string("Cursos"));
    
    cout << "Palavra: " << *pal << endl;
    cout << "Tamanho: " << pal->size() << endl;
    
    

    Crie fora do main, uma classe simples com esse código:

    
    class Carro {
        public:
            int vel = 0;
            
            int getVel() {
                return vel;
            }
            void setVel(int v) {
                this->vel = v;
            }
    };
    
    

    E crie um objeto com o método tradicional assim:

    
    Carro *c1 = new Carro();
    
    c1->setVel(100);
    
    cout << "Velocidade: " << c1->getVel() << endl;
    
    delete c1;
    
    

    Mesmo código acima, só que com ponteiro inteligente:

    
    unique_ptr<Carro> c1(new Carro());
    
    c1->setVel(100);
    
    cout << "Velocidade: " << c1->getVel() << endl;
    
    

    Outro exemplo, usando o shared_ptr com um segundo objeto:

    
    shared_ptr<Carro> c1(new Carro());
    shared_ptr<Carro> c2 = c1;
    
    c1->setVel(100);
    c2->setVel(80);
        
    cout << "Velocidade: " << c1->getVel() << endl;
    cout << "Velocidade: " << c2->getVel() << endl;
    
    

    Observe que no código acima, ambos os objetos retornam 80, porque usam o mesmo ponteiro, e portanto, o método de um altera/captura características do outro, por compartilhamento.

    Para que cada ponteiro tenhas suas características particulares, use o unique_ptr mesmo:

    
    unique_ptr<Carro> c1(new Carro());
    unique_ptr<Carro> c2(new Carro());
    
    c1->setVel(100);
    c2->setVel(80);
    
    cout << "Velocidade: " << c1->getVel() << endl;
    cout << "Velocidade: " << c2->getVel() << endl;
    
    

    No C++ 11, caso precise inicializar um ponteiro como nulo, podemos usar nullptr no lugar do NULL.

    Algoritmo For_Each em C++ 11

    O algoritmo for each é mais uma maneira para percorrer um container, usando uma função lambda para isso.

    Para trabalhar com foreach, precisamos importar a biblioteca algorithm.

    Veja um exemplo de código com iterator:

    
    vector<int> n{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    vector<int>::iterator it;
    
    for(it = n.begin(); it != n.end(); it++) {
        cout << *it << endl;
    }
    
    

    Ou simplificando:

    
    vector<int> n{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    
    for(auto it = n.begin(); it != n.end(); it++) {
        cout << *it << endl;
    }
    
    

    Simplificando mais ainda (essa é a forma mais simples de escrever):

    
    vector<int> n{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    
    for(auto it: n) {
        cout << it << endl;
    }
    
    

    E claro, podemos usar o for tradicional também.

    Mas não é difícil fazer com o for each, que é uma função, que recebe uma função lambda, veja como usar:

    
    vector<int> n{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    
    for_each(n.begin(), n.end(), [](int num){cout << num << endl;}); // Inclua algorithm
    
    

    Em outras palavras, os parâmetros são o dado inicial, o dado final e a função, que é preferível ser lambda.

    Podemos também colocar outras operações dentro dessa função lambda, por exemplo:

    
    vector<int> n{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    
    for_each(n.begin(), n.end(), [](int num) {
        num += 10;
        cout << num << endl;
    });
    
    

    PS: A alteração acima só acontece dentro do lambda, ele não altera os dados do vector, como podem ver, usando outro for each:

    
    vector<int> n{0, 1, 2, 3, 4, 5, 6, 7, 8, 9};
    
    for_each(n.begin(), n.end(), [](int num) {
        num += 10;
        cout << num << endl;
    });
    
    cout << endl;
    
    for_each(n.begin(), n.end(), [](int num) {
        cout << num << endl;
    });