cpp_tips
Rozdíly
Zde můžete vidět rozdíly mezi vybranou verzí a aktuální verzí dané stránky.
| Obě strany předchozí revizePředchozí verzeNásledující verze | Předchozí verze | ||
| cpp_tips [2016/05/11 14:19] – [Převod struct na/z string (serializace)] djbuldog | cpp_tips [2025/08/28 10:09] (aktuální) – upraveno mimo DokuWiki 127.0.0.1 | ||
|---|---|---|---|
| Řádek 1: | Řádek 1: | ||
| ====== Tipy & triky C++ ====== | ====== Tipy & triky C++ ====== | ||
| - | ===== char* do istringstrem ===== | + | ===== char* na istringstrem |
| Řádek 21: | Řádek 21: | ||
| * ověřil jsem to zavoláním free na mybuff (kód se musí upravit na dynamickou alokaci mybuf) | * ověřil jsem to zavoláním free na mybuff (kód se musí upravit na dynamickou alokaci mybuf) | ||
| + | * metoda [[http:// | ||
| + | |||
| + | ===== char* do vector< | ||
| + | |||
| + | <code cpp> | ||
| + | char arr[] = " | ||
| + | vector< | ||
| + | buf-> | ||
| + | </ | ||
| + | |||
| + | ===== stringstream na cout/string ===== | ||
| + | |||
| + | * na příkladu | ||
| + | |||
| + | <file cpp stringstream_test.cpp> | ||
| + | #include < | ||
| + | |||
| + | using namespace std; | ||
| + | |||
| + | int main() { | ||
| + | |||
| + | stringstream ss(" | ||
| + | ostringstream os(" | ||
| + | istringstream is(" | ||
| + | |||
| + | ss.get(); | ||
| + | cout << " | ||
| + | cout << " | ||
| + | cout << " | ||
| + | cout << " | ||
| + | |||
| + | is.get(); | ||
| + | cout << " | ||
| + | cout << " | ||
| + | cout << " | ||
| + | cout << " | ||
| + | |||
| + | // | ||
| + | cout << " | ||
| + | cout << " | ||
| + | //cout << " | ||
| + | cout << " | ||
| + | |||
| + | cout << " | ||
| + | |||
| + | stringstream ss2; | ||
| + | ostringstream os2(" | ||
| + | istringstream is2(" | ||
| + | |||
| + | char my1[]=" | ||
| + | char my2[]=" | ||
| + | char my3[]=" | ||
| + | |||
| + | ss2.rdbuf()-> | ||
| + | os2.rdbuf()-> | ||
| + | is2.rdbuf()-> | ||
| + | |||
| + | ss2.get(); | ||
| + | cout << " | ||
| + | cout << " | ||
| + | cout << " | ||
| + | cout << " | ||
| + | |||
| + | is2.get(); | ||
| + | cout << " | ||
| + | cout << " | ||
| + | cout << " | ||
| + | cout << " | ||
| + | |||
| + | // | ||
| + | cout << " | ||
| + | cout << " | ||
| + | //cout << " | ||
| + | cout << " | ||
| + | |||
| + | } | ||
| + | </ | ||
| + | |||
| + | * spuštění vypíše | ||
| + | |||
| + | < | ||
| + | 1: | ||
| + | 2:SS | ||
| + | 3:S | ||
| + | 4:SS | ||
| + | 1: | ||
| + | 2:IS | ||
| + | 3:S | ||
| + | 4:IS | ||
| + | 1: | ||
| + | 2:OS | ||
| + | 4:OS | ||
| + | --- | ||
| + | 1: | ||
| + | 2:SS2 | ||
| + | 3:S2 | ||
| + | 4:SS2 | ||
| + | 1: | ||
| + | 2: | ||
| + | 3:S2 | ||
| + | 4: | ||
| + | 1: | ||
| + | 2:OS2 | ||
| + | 4:OS2 | ||
| + | </ | ||
| + | |||
| + | * všimni si, že přečtení znaku z '' | ||
| + | * řeší se to přenastavením ukazatele a preventivním vymazáním flagů (například EOF flag) | ||
| + | |||
| + | <code cpp> | ||
| + | is.clear(); | ||
| + | is.seekg(0); | ||
| + | </ | ||
| + | |||
| + | * dále, po nastavení bufferu přes '' | ||
| + | * na příčinu jsem zatím nepřišel, ale řešení je použít '' | ||
| ===== Default parametry metody/ | ===== Default parametry metody/ | ||
| Řádek 120: | Řádek 236: | ||
| * čtení probíhá obdobně... voláním funkce read | * čtení probíhá obdobně... voláním funkce read | ||
| + | |||
| + | ===== Mapování struct do vector< | ||
| + | |||
| + | <code cpp> | ||
| + | vector< | ||
| + | mystruct *s = reinterpret_cast< | ||
| + | </ | ||
| + | |||
| + | ===== Velikost struktury s polem znaků ===== | ||
| + | |||
| + | * platí v C/C++ | ||
| + | * jak velká je tato struktura? | ||
| + | <code c> | ||
| + | struct mystruct { | ||
| + | char data[]; | ||
| + | } | ||
| + | </ | ||
| + | * sizeof hlasí 0B :) | ||
| + | * pokud ji chceme započítat, | ||
| + | <code c> | ||
| + | struct mystruct { | ||
| + | char data[1]; | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== Private Hader file ===== | ||
| + | |||
| + | * třídy se typicky deklarují v hlavičkovém souboru | ||
| + | * třída má někdy privátní položku speciálního datového typu, který vyžaduje vložit speciální hlavičkový soubor | ||
| + | * pokud třídu využíváme v jiné třídě, zbytečně vkládáme další a další hlavičkové soubory | ||
| + | * přitom nás privátní položky jiné třídy vůbec nezajímají, | ||
| + | * vzniká tak potřeba tzv privátních a veřejných hlavičkových souborů | ||
| + | * další využití je pro skrytí vnitřní implementace třídy | ||
| + | |||
| + | * řešení s jedním hlavičkovým | ||
| + | * do hlavičkového přidáme podmínky.. | ||
| + | |||
| + | <code cpp> | ||
| + | #ifdef CONF_IMPL | ||
| + | #include < | ||
| + | #include < | ||
| + | #endif | ||
| + | |||
| + | .. | ||
| + | |||
| + | class Conf { | ||
| + | |||
| + | private: | ||
| + | .. | ||
| + | #ifdef ADSCONF_IMPL | ||
| + | void parsePref(xmlNodePtr cur); | ||
| + | void parseMet(xmlNodePtr cur); | ||
| + | void parseCfg(xmlNodePtr cur); | ||
| + | #endif | ||
| + | .. | ||
| + | | ||
| + | public: | ||
| + | Conf(); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | * do zdrojového kódu, kde třídu implementujeme, | ||
| + | |||
| + | ===== Memory leak bez virtuálního destruktoru ===== | ||
| + | |||
| + | * pokud se z třídy dědí, měla by mít virtuální destruktor | ||
| + | * memory leak příklad: | ||
| + | <code cpp> | ||
| + | class Interface | ||
| + | { | ||
| + | | ||
| + | }; | ||
| + | |||
| + | class Derived : public Interface | ||
| + | { | ||
| + | | ||
| + | | ||
| + | { | ||
| + | // Do some important cleanup... | ||
| + | } | ||
| + | }; | ||
| + | |||
| + | void myFunc(void) | ||
| + | { | ||
| + | | ||
| + | // The behaviour of the next line is undefined. It probably | ||
| + | // calls Interface:: | ||
| + | | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | * je to zajímavé, protože ve třídě nemusí být vůbec dynamická alokace. Stačí, aby měla jako member nějaký objekt, třeba string, a bez zavolaní správného destruktoru nedojde k dealokaci | ||
| + | * řešení je přidat virtuální destruktor do Base třídy, stačí takto: | ||
| + | <code cpp> | ||
| + | virtual ~Interface() {} | ||
| + | </ | ||
| + | |||
| + | |||
| + | ===== Soubor do paměti ===== | ||
| + | |||
| + | <code c++> | ||
| + | ifstream sfile(filepath.c_str()); | ||
| + | if (!sfile) { | ||
| + | LogMsg(MSGERR, | ||
| + | flen = 0; | ||
| + | } else { | ||
| + | |||
| + | // checking file size... is getFileSize() better? | ||
| + | sfile.seekg(0, | ||
| + | flen = sfile.tellg(); | ||
| + | sfile.seekg(0, | ||
| + | |||
| + | vector< | ||
| + | sfile.read(& | ||
| + | |||
| + | sfile.close(); | ||
| + | } | ||
| + | </ | ||
| + | |||
| + | ===== Paměť do souboru ===== | ||
| + | |||
| + | <code c++> | ||
| + | ofstream f; | ||
| + | |||
| + | f.open(filepath.c_str()); | ||
| + | if (!f.is_open()) { | ||
| + | LogMsg(MSGERR, | ||
| + | return 7; | ||
| + | } | ||
| + | |||
| + | f.write(v.data(), | ||
| + | f << flush; // force to create empty file | ||
| + | f.close(); | ||
| + | </ | ||
cpp_tips.1462969183.txt.gz · Poslední úprava: (upraveno mimo DokuWiki)
