23. cvičení

Komentáře k jazyku C++, hlavní rozdíly oproti jazyku C.

Vlastnosti jazyka C, které nefungují v C++

  1. Vícerozměrné pole – viz 8. cvičení.
  2. Implicitní přetypování ukazatelů – v jazyce C povoleno, v jazyce C++ ne.

    Např. následující příkaz nefunguje v jazyce C++, protože ukazatel typu void* (návratový typ funkce malloc) nelze implicitně převést na typ int*:

    int* pole = malloc(velikost * sizeof(int));
    

    Oprava pro jazyk C++ spočívá v explicitním přetypování vrácené hodnoty:

    int* pole = (int*) malloc(velikost * sizeof(int));
    

Vlastnosti jazyka C++, které nefungují v C

(Pro zdrojové soubory v jazyce C++ se běžně používá koncovka .cpp namísto .c.)

Reference

Reference slouží k vytvoření jiného názvu pro stejnou proměnnou. Do jisté míry jsou podobné ukazatelům, ale není je třeba dereferencovat (*ukazatel) a v případě referencí na struktury se stále používá operátor tečka (.) (v případě ukazatelů na struktury jsme museli použít operátor šipka (->)). Referenci ale nejde „přereferencovat“, neboli po vytvoření odkázat na jinou proměnnou.

Příklad:

#include <stdio.h>

int main()
{
    // promenna
    int a = 42;

    // ukazatel
    int* u = &a;
    printf("hodnota = %d\n", *u);

    // reference
    int& r = a;
    a = 1;
    printf("hodnota = %d\n", r);
    r = 2;
    printf("hodnota = %d\n", a);
}

Přetěžování funkcí

Přetěžování funkcí je vlastnost jazyka C++, díky které je možné v určitých případech (ne vždy!) definovat několik funkcí se stejným názvem a nechat překladač, aby sám vybral, kterou funkci má v jednotlivých případech použít.

Příklad:

#include <stdio.h>

int max(int n, int* pole)
{
    int vysledek = pole[0];
    for (int i = 1; i < n; i++) {
        if (pole[i] > vysledek)
            vysledek = pole[i];
    }
    return vysledek;
}

float max(int n, float* pole)
{
    float vysledek = pole[0];
    for (int i = 1; i < n; i++) {
        if (pole[i] > vysledek)
            vysledek = pole[i];
    }
    return vysledek;
}

int main()
{
    int pole1[10];
    float pole2[10];
    for (int i = 0; i < 10; i++) {
        pole1[i] = i;
        pole2[i] = i + 0.5;
    }

    int m1 = max(10, pole1);    // prekladac pouzije prvni funkci
    float m2 = max(10, pole2);  // prekladac pouzije druhou funkci

    printf("m1 = %d, m2 = %f\n", m1, m2);
    return 0;
}

Jmenné prostory

Jmenné prostory slouží k oddělení funkcí, typů, struktur a dalších prvků jazyka C++, aby nedocházelo ke kolizím v pojmenování. Jejich použití se hodí zejména pro zpřehlednění větších projektů.

Příklad použití:

#include <stdio.h>

namespace A {
    void funkce()
    {
        printf("Funkce 1\n");
    }
}

namespace B {
    void funkce()
    {
        printf("Funkce 2\n");
    }
}

int main()
{
    A::funkce();
    B::funkce();

    {
        using namespace A;
        funkce();
    }

    {
        using namespace B;
        funkce();
    }

    return 0;
}

Nejdůležitější jmenný prostor se jmenuje std a jsou v něm dostupné všechny funkce, typy, struktury a další prvky standardní knihovny jazyka C++.

Základní objekty ve standardní knihovně jazyka C++

  1. std::cout – globální objekt (proměnná) reprezentující standardní výstup
  2. std::endl – globální objekt (proměnná) reprezentující znak pro ukončení řádku

    Tyto objekty jsou dostupné v hlavičkovém souboru <iostream>. Pro výpis hodnot proměnných, textových řetězců apod. lze použít přetížený operátor <<. Základní program „hello, world“ v jazyku C++ vypadá takto:

    #include <iostream>
    
    int main()
    {
        std::cout << "Hello, world" << std::endl;
        return 0;
    }
    
  3. std::cin – globální objekt (proměnná) reprezentující standardní vstup

    Hodnoty ze standardního vstupu můžeme získat pomocí přežíženého operátoru >>:

    int a = 0;
    std::cout << "Zadej cele cislo: ";
    std::cin >> a;
    
    float b = 0;
    std::cout << "Zadej desetinne cislo: ";
    std::cin >> b;
    
  4. std::string – struktura/třída pro reprezentaci textových řetězců v jazyce C++. Je dostupná v hlavičkovém souboru string.

    Pro práci s objekty jsou k dispozici tzv. metody, neboli funkce svázané s určitým objektem. Místo abychom funkci předávali objekt pomocí parametru (např. strlen(retezec) v jazyce C), voláme metodu daného objektu pomocí operátoru tečka (např. retezec.length() v jazyce C++).

    Příklad:

    #include <iostream>
    #include <string>
    
    int main()
    {
        std::string s = "Hello, world";
        s.insert(5, "!!!");
        s += " text";
    
        int delka = s.length();
    
        std::cout << s << std::endl;
        std::cout << delka << std::endl;
    
        return 0;
    }
    

    Viz také seznam metod třídy std::string.

Úvod do objektově orientovaného programování – vytváření vlastních objektů

Pro vytváření objektů v jazyce C++ slouží třídy (nebo struktury – v jazyce C++ se téměř neliší od tříd). Třídy jsou v podstatě struktury jazyka C doplněné o tzv. metody, neboli funkce svázané s konkrétním objektem (viz předchozí příklad).

Speciální metody každé třídy jsou:

  1. konstruktor – volá se automaticky při vytváření objektu
  2. destruktor – volá se automaticky při zániku objektu (např. na konci funkce, ve které byla vytvořena automatická proměnná)

Definice třídy dále obsahuje sekce public: (atributy dostupné zvenku) a private: (atributy dostupné pouze z metod definovaných v dané třídě).

Příklad:

#include <iostream>

class zlomek
{
private:
    int citatel;
    int jmenovatel;

public:
    // konstruktor
    zlomek()
    {
        citatel = 0;
        jmenovatel = 1;
    }

    zlomek(int c, int j = 1)
    {
        citatel = c;
        jmenovatel = j;
    }

    // destruktor
    ~zlomek()
    {
    }

    // vlastni metody
    void vypis()
    {
        std::cout << citatel << "/" << jmenovatel << std::endl;
    }

    // operatory
    zlomek operator*(zlomek z)
    {
        zlomek vysledek;
        vysledek.citatel = citatel * z.citatel;
        vysledek.jmenovatel = jmenovatel * z.jmenovatel;
        return vysledek;
    }

    // dalsi operatory: operator/, operator+, operator-
};

int main()
{
    zlomek z1(2, 3);
    zlomek z2(4);
    zlomek z3 = z1 * z2;

    z3.vypis();

    return 0;
}

Další vlastnosti jazyka C++

  1. Zpracování chyb pomocí výjimek.
  2. Šablony.