6 zpracovanych otazek v programovani c++
This commit is contained in:
@@ -59,11 +59,110 @@ Poznámka: Příklady jsou zjednodušené a ne vždy jsou 100% syntakticky práv
|
|||||||
- Jaký je rozdíl mezi mělkou a hlubokou kopií?
|
- Jaký je rozdíl mezi mělkou a hlubokou kopií?
|
||||||
# Programování v C++
|
# Programování v C++
|
||||||
### 1) Napište příklad načteni hodnoty typu int ze standarního vstupu pomocí proudového operátoru. Jak lze ošetřit správnost vstupu?
|
### 1) Napište příklad načteni hodnoty typu int ze standarního vstupu pomocí proudového operátoru. Jak lze ošetřit správnost vstupu?
|
||||||
|
```cpp
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
int x;
|
||||||
|
if(std::cin >> x)
|
||||||
|
{
|
||||||
|
std::cout << "ok";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
std::cout << "chyba";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Tenhle příklad načte hodnotu pomocí `std::cin >> x`, kde `x` je proměnná a `std::cin` je standardní input stream.
|
||||||
|
|
||||||
|
`std::cin >> x` vrací hodnotu `true` pokud je vše v pořádku a `false` pokud ne. Pokud se načte něco jiného jak číslo, tak třeba vrací false.
|
||||||
|
|
||||||
|
Kokrétněji `std::cin` má několik stavových bitů a to **fail** -> který je nastavený, když se něco pokazí (například špatný převod na typ -> string na int, etc.), **eof** -> který je nastavený, když je konec input streamu, **bad** -> který je nastavený, když se opravdu něco pokazí.
|
||||||
|
|
||||||
|
Když přečtu poslední znak, automaticky se nastaví eof bit a ten můžu zkontrolova pomocí `std::cin.eof() == true`. Složitější je, když se něco pokazí. To může být např. při špatném převodu nebo, když čtu po konci streamu a **je třeba to opravit**.
|
||||||
|
Nejprve je třeba nastavit `std::cin.clear()`, což vynuluje bity, takže můžu pokračovat ve čtení. To ale nestačí. Nezpracovaný text zůstane uložený v bufferu a přečte se znova příště. To jde vyřešit pomocí funkce `std::cin.ignore(int, char)`, kde int je počet znaků, co to vymaže a char je znak, kterým to končí, například `std::cin.ignore(1000, '\n')` vymaže 1000 znaků do konce řádky.
|
||||||
|
|
||||||
|
Btw `if(std::cin >> x)` vlastně vrací `if(!std::cin.fail())`
|
||||||
|
|
||||||
|
|
||||||
### 2) Jak se v C++ provádí přetížení operátoru? Uveďte příklad.
|
### 2) Jak se v C++ provádí přetížení operátoru? Uveďte příklad.
|
||||||
|
Přetěžování operátorů je implementace fungování znaků operátorů jako `+`, `-`, `>`, etc. pro objekty tříd, co napíšu.
|
||||||
|
Jsou dva způsoby jak to udělat. Buď na to napíšu funkci uvnitř třídy, pro kterou to chci implementovat, nebo na to napíšu samostatnou funkci mimo.
|
||||||
|
|
||||||
|
Používám na to speciální název funkce `operator`, ke které napíšu, jaký operátor řeším
|
||||||
|
Příklad uvnitř třídy:
|
||||||
|
```cpp
|
||||||
|
class Number
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int n;
|
||||||
|
Number(int set_n) {n = set_n;}
|
||||||
|
|
||||||
|
Number operator+(const Number &numA) //reference na objekt napravo od +
|
||||||
|
{
|
||||||
|
return Number(this->n + numA.n)
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
int main(void)
|
||||||
|
{
|
||||||
|
Number a(10);
|
||||||
|
Number b(20);
|
||||||
|
|
||||||
|
Number c = a + b;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Nebo mimo třídu to může vypadat například takto:
|
||||||
|
```cpp
|
||||||
|
Number operator+(const Vec& a, const Vec& b)
|
||||||
|
{
|
||||||
|
return Vec{a.x + b.x};
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Btw, reference se používají, protože nekopírovat hodnoty, ale jenom na ně ukazovat, je šetrnější.
|
||||||
|
|
||||||
|
**Na tohle téma jsem udělal samostatný dokument na githubu (Přetěžování operátorů)**
|
||||||
### 3) Jaké operátory nelze v C++ přetížit?
|
### 3) Jaké operátory nelze v C++ přetížit?
|
||||||
### Jak a kdy se volá konstruktor a destruktor?
|
Přetěžovat nelze operátory:
|
||||||
### Jaký je rozdíl mezi objektem alokovaným v zásobníku a objektem dynamicky alokovaným na haldě?
|
- `.`
|
||||||
### Jaký je rozdíl mezi operátory `delete` a `delete[]`?
|
- `::`
|
||||||
|
- `?:`
|
||||||
|
- `sizeof`
|
||||||
|
- `typeid`
|
||||||
|
|
||||||
|
Většinou to je proto, protože jsou v syntaxi tak důležité, že by to mohlo udělat nejasnosti v tom, jak by to měl vůbec kompilátor překládat. (Má tečku řešit jako člen, nebo jako něco úplně jiného... etc.) **Ty operátory totiž už většinou mají funkční účel předtím, než jsou přetížené a to u operátorů, co jdou přetížit neplatí.**
|
||||||
|
|
||||||
|
Na tohle téma jsem zpracoval mimochodem dokument na githubu.
|
||||||
|
### 4) Jak a kdy se volá konstruktor a destruktor?
|
||||||
|
Konstruktor se zavolá při vytvoření objektu. Můžu do něj dát jako argument hodnoty, které chci třeba využít při inicializaci.
|
||||||
|
|
||||||
|
Mám dva typa alokace objektů, které se dělají jinak. Jedna je statická a druhá je dynamická.
|
||||||
|
Staticky alokuju objektu takto: `Trida objekt(...);` a dynamicky pomocí **new**: `Trida* objekt = new Trida;`. Je v tom zásadní rozdíl v životnosti objektu. -> viz další otázka:
|
||||||
|
|
||||||
|
Destruktor se u statického objektu zavolá sám, když se dojde ke konci scopu (bloku kódu, funkce, etc...). Nemusím ho volat a ani bych neměl.
|
||||||
|
|
||||||
|
U dynamického objektu ho musím zavolat manuálně pomocí `delete objekt;` nebo v případě pole objektů pomocí `delete[] pole_objektu;`
|
||||||
|
|
||||||
|
Pozn: klasický dynamický objekt se řeší pomocí ukazatele na objekt a dereference
|
||||||
|
### 5) Jaký je rozdíl mezi objektem alokovaným v zásobníku a objektem dynamicky alokovaným na haldě?
|
||||||
|
|
||||||
|
- Statické objekty se automaticky zníčí, když opustí scope -> blok, funkci, etc.
|
||||||
|
- Dynamické objekty zůstávají v paměti, než jsou zničeny pomocí delete
|
||||||
|
|
||||||
|
Používají se často alternativy, například smart pointer -> drží pointer v objektu a když se zníčí, zníčí i dynamický objekt.
|
||||||
|
### 6) Jaký je rozdíl mezi operátory `delete` a `delete[]`?
|
||||||
|
- `delete` se používá pro uvolňování dynamického objektu
|
||||||
|
- `delete[]` se používá pro uvolňování pole objektů
|
||||||
|
|
||||||
|
```cpp
|
||||||
|
Trida* objekty = new Trida[7];
|
||||||
|
delete[] objekty; //uvolni cele pole objektu
|
||||||
|
```
|
||||||
### Jaká je návratová hodnota destruktoru?
|
### Jaká je návratová hodnota destruktoru?
|
||||||
### Co je třeba zajistit při dynamické alokaci? Uveďte příklad.
|
### Co je třeba zajistit při dynamické alokaci? Uveďte příklad.
|
||||||
### Co je to výjimka a k čemu je dobrá? Uveďte příklad.
|
### Co je to výjimka a k čemu je dobrá? Uveďte příklad.
|
||||||
|
|||||||
Reference in New Issue
Block a user