abclinuxu.cz AbcLinuxu.cz itbiz.cz ITBiz.cz HDmag.cz HDmag.cz abcprace.cz AbcPráce.cz
AbcLinuxu hledá autory!
Inzerujte na AbcPráce.cz od 950 Kč
Rozšířené hledání
×
    dnes 01:11 | Bezpečnostní upozornění

    Red Hat řeší bezpečnostní incident, při kterém došlo k neoprávněnému přístupu do GitLab instance používané jejich konzultačním týmem.

    Ladislav Hagara | Komentářů: 0
    včera 23:33 | Nová verze

    Immich byl vydán v první stabilní verzi 2.0.0 (YouTube). Jedná se o alternativu k výchozím aplikacím od Googlu a Applu pro správu fotografií a videí umožňující vlastní hosting serveru Immich. K vyzkoušení je demo. Immich je součástí balíčků open source aplikací FUTO. Zdrojové kódy jsou k dispozici na GitHubu pod licencí AGPL-3.0.

    Ladislav Hagara | Komentářů: 0
    včera 22:33 | IT novinky

    Český telekomunikační úřad vydal zprávy o vývoji cen a trhu elektronických komunikací se zaměřením na rok 2024. Jaká jsou hlavní zjištění? V roce 2024 bylo v ČR v rámci služeb přístupu k internetu v pevném místě přeneseno v průměru téměř 366 GB dat na jednu aktivní přípojku měsíčně – celkově jich tak uživateli bylo přeneseno přes 18 EB (Exabyte). Nejvyužívanějším způsobem přístupu k internetu v pevném místě zůstal v roce 2024 bezdrátový

    … více »
    Ladislav Hagara | Komentářů: 0
    včera 12:11 | Nová verze

    Raspberry Pi OS, oficiální operační systém pro Raspberry Pi, byl vydán v nové verzi 2025-10-01. Přehled novinek v příspěvku na blogu Raspberry Pi a poznámkách k vydání. Jedná o první verzi postavenou na Debianu 13 Trixie.

    Ladislav Hagara | Komentářů: 0
    včera 05:22 | Nová verze

    Byla vydána nová verze 4.6 svobodného notačního programu MuseScore Studio (Wikipedie). Představení novinek v oznámení v diskusním fóru a také na YouTube.

    Ladislav Hagara | Komentářů: 0
    včera 02:22 | Komunita

    Společnost DuckDuckGo stojící za stejnojmenným vyhledávačem věnovala 1,1 milionu dolarů (stejně jako loni) na podporu digitálních práv, online soukromí a lepšího internetového ekosystému. Rozdělila je mezi 29 organizací a projektů. Za 15 let rozdala 8 050 000 dolarů.

    Ladislav Hagara | Komentářů: 4
    1.10. 20:11 | Nová verze

    Svobodný multiplatformní herní engine Bevy napsaný v Rustu byl vydán ve verzi 0.17. Díky 278 přispěvatelům.

    Ladislav Hagara | Komentářů: 0
    1.10. 16:11 | Nová verze

    Bylo vydáno openSUSE Leap 16 (cs). Ve výchozím nastavení přichází s vypnutou 32bitovou (ia32) podporou. Uživatelům však poskytuje možnost ji ručně povolit a užívat si tak hraní her ve Steamu, který stále závisí na 32bitových knihovnách. Změnily se požadavky na hardware. Leap 16 nyní vyžaduje jako minimální úroveň architektury procesoru x86-64-v2, což obecně znamená procesory zakoupené v roce 2008 nebo později. Uživatelé se starším hardwarem mohou migrovat na Slowroll nebo Tumbleweed.

    Ladislav Hagara | Komentářů: 3
    1.10. 16:00 | IT novinky

    Ministerstvo průmyslu a obchodu (MPO) ve spolupráci s Národní rozvojovou investiční (NRI) připravuje nový investiční nástroj zaměřený na podporu špičkových technologií – DeepTech fond. Jeho cílem je posílit inovační ekosystém české ekonomiky, rozvíjet projekty s vysokou přidanou hodnotou, podpořit vznik nových technologických lídrů a postupně zařadit Českou republiku mezi země s nejvyspělejší technologickou základnou.

    … více »
    Ladislav Hagara | Komentářů: 3
    1.10. 12:55 | Nová verze

    Radicle byl vydán ve verzi 1.5.0 s kódovým jménem Hibiscus. Jedná se o distribuovanou alternativu k softwarům pro spolupráci jako např. GitLab.

    Ladislav Hagara | Komentářů: 3
    Jaké řešení používáte k vývoji / práci?
     (40%)
     (47%)
     (14%)
     (16%)
     (18%)
     (14%)
     (18%)
     (14%)
     (14%)
    Celkem 159 hlasů
     Komentářů: 10, poslední dnes 01:37
    Rozcestník

    Dotaz: C++ shared_ptr - constrainty

    3.12.2020 01:45 mokere
    C++ shared_ptr - constrainty
    Přečteno: 539×
    Mám 2 pointery ukazujúce na 2 objekty (iterator a stream). Iterátor prechádza stream. Jeden z tých pointerov (iterator) vracia funkcia ReadLines. Ten druhý by sa mal uvolniť spolu s tým prvým. Ako na to? Skúmal som dokumentáciu a našiel som tam parameter konštruktora Deleter ktorý som využil na zmazanie oboch pointerov vo chcíli keď by sa mal zmazať smart pointer ukazujúci na iterator:
    namespace
    {
    	template<typename CharType = wchar_t>
    	std::basic_istream<CharType>& operator>>(std::basic_istream<CharType>& inputStream, std::basic_string<CharType>& line)
    	{
    		std::getline(inputStream, line);
    		return inputStream;
    	}
    }
    
    template<typename CharType = char>
    auto ReadLines(std::wstring path)
    {
    	auto inputStream = new std::ifstream(path);
    	using iterator = std::istream_iterator<std::basic_string<CharType>>;
    	auto begin = std::shared_ptr<iterator>(
    		new iterator(*inputStream),
    		[inputStream](auto* iterator)
    		{
    			delete iterator;
    			delete inputStream;
    		}
    	);
    	return begin;
    }
    Je toto správne riešenie? Alebo na to idem zle? Lebo fungovať mi to funguje. Ak viete o niečom priamočiarejšom tak sem s tým. Ďakujem.

    Odpovědi

    3.12.2020 01:53 mokere
    Rozbalit Rozbalit vše Re: C++ shared_ptr - constrainty
    A takto sa potom volá funkcia ReadLines:
    auto begin = ReadLines(L"c:\test\newFile21.txt");
    for (auto it = *begin; it != std::istream_iterator<std::string>(); ++it)
    {
    	std::cout << ":" << *it << "n";
    }
    3.12.2020 01:56 mokere
    Rozbalit Rozbalit vše Re: C++ shared_ptr - constrainty
    nejako blbne escapovanie, namiesto n tam malo byť lomitko a n resp std::endl
    3.12.2020 09:20 MadCatX | skóre: 28 | blog: dev_urandom
    Rozbalit Rozbalit vše Re: C++ shared_ptr - constrainty
    #include <fstream>
    #include <iostream>
    #include <stdexcept>
    
    template <typename T>
    void read_lines(const std::string &path, T &&handler)
    {
            std::ifstream s{};
            s.open(path);
            if (!s.is_open())
                    throw std::runtime_error{"Cannot open file"};
    
            std::string str{};
            while (std::getline(s, str).good())
                    handler(str);
    }
    
    int main()
    {
            try {
                    read_lines("abc.txt", [](const std::string &s) { std::cout << s << std::endl; });
            } catch (const std::runtime_error &ex) {
                    std::cout << ex.what() << std::endl;
            }
    
            return 0;
    }
    
    3.12.2020 10:50 10minuteman
    Rozbalit Rozbalit vše Re: C++ shared_ptr - constrainty
    Obecne, jak mas nekde nahe new & delete, vis, ze to nepises dobre. Spravne je vyuzit RAII a vytvorit si nejakou guard tridu: new volas v konstruktoru, delete v destruktoru. Pak mas jistotu, ze se spravne uvolni tvuj resource i pri nestandardnim ukonceni scope (treba pri vyhozeni vyjimky). No ale jelikoz std typy tak uz funguji (tedy svuj resource si hlida uz treba ten ifstream), nemusis to nijak resit a napis to tak, jak ti radi MadCatX.

    Za druhe, std::shared_ptr (a podobne veci) inicializuj pomoci std::make_shared (a podobnych funkci) - je to bezpecnejsi a rychlejsi.
    3.12.2020 19:07 Andrej | skóre: 51 | blog: Republic of Mordor
    Rozbalit Rozbalit vše Re: C++ shared_ptr - constrainty

    Začal bych od jednoduchého příkladu — implicitní iterace po slovech. To se zařídí třeba takhle:

    #include <fstream>
    #include <iostream>
    #include <iterator>
    #include <string>
    
    namespace {
    
    template<typename C>
    struct ifstream_iterable {
      ifstream_iterable(const std::string &path) : stream_{path} {}
      auto begin() { return iterator{stream_}; }
      auto end() { return iterator{}; }
     private:
      typedef std::istream_iterator<std::basic_string<C>, C> iterator;
      std::basic_ifstream<C> stream_;
    };
    
    }  // namespace
    
    int main() {
      for (auto &w : ifstream_iterable<wchar_t>{"/proc/cpuinfo"})
        std::wcout << w << std::endl;
    }
    

    To bychom měli. Teď je otázka, jak z toho^^^ udělat iteraci po řádcích. Předně pár poznámek k tématu:

    • Tvůj příklad s operátorem >> je mírně špatně v mezích zákona, protože deklarace je hodně podobná této deklaraci v headeru <string>, což sice na první pohled nevadí, ale na druhý pohled tam hraje roli až příliš mnoho složitých detailů kolem pravidel pro hledání identifikátorů. Drobná změna standardu a/nebo (kni)hovny může vést k tomu, že operátor se buď vůbec nepoužije, nebo začne být v konfliktu s operátory z (kni)hovny. Drobnou modifikací se mi podařilo vyrobit (proti)příklad, kdy clang++ i g++ kód přeloží bez varování, ale g++ „přetížený“ operátor použije, zatímco clang++ nikoliv.
    • Jedno (nechvalně) známé řešení ze Zásobníkovéhopřetečení sice vypadá na první pohled hezky a jednoduše, ale vyskytují se v něm tři poněkud nepříjemné a sporné nápady:

      • soukromá dědičnost (která se tu a tam hodí, ale tenhle případ není ani tu, ani tam)
      • kámoši (kterým je ideální se vyhnout, protože všeho všudy ukazují na chybu v návrhu (zapouzdření atd.))
      • dědění od std::string (což je sice technicky možné, ale z hlediska kompatibility a udržovatelnosti kódu je vhodné se takových nápadů vyvarovat)

    Co tedy podniknout? Třeba tohle:

    #include <fstream>
    #include <iostream>
    #include <iterator>
    #include <string>
    #include <utility>
    
    namespace {
    
    template <typename C>
    struct line {
      std::basic_istream<C>& operator <<(std::basic_istream<C> &stream) {
        std::getline(stream, str_);
        return stream;
      }
      operator const std::basic_string<C>&() const & { return str_; }
      operator std::basic_string<C>&() & { return str_; }  // zde se nepoužije
      operator std::basic_string<C>() && { return std::move(str_); }  // -dtto-
     private:
      std::basic_string<C> str_;
    };
    
    template <typename C>
    std::basic_istream<C>& operator >>(std::basic_istream<C> &stream,
                                       line<C> &str) {
      str << stream;
      return stream;
    }
    
    template<typename C>
    struct ifstream_iterable {
      ifstream_iterable(const std::string &path) : stream_{path} {}
      auto begin() { return iterator{stream_}; }
      auto end() { return iterator{}; }
     private:
      typedef std::istream_iterator<line<C>, C> iterator;
      std::basic_ifstream<C> stream_;
    };
    
    }  // namespace
    
    int main() {
      for (const std::wstring &l : ifstream_iterable<wchar_t>{"/proc/cpuinfo"})
        std::wcout << l << std::endl;
    }
    

    Tohle^^^ nedědí od základních typů, nevyvolává příliš mnoho nespecifikovaných rohových případů, nepoužívá kámoše a vystačí si s jednou třídou (dělnickou), kterou lze konvertovat na odpovídající string. (Pro složitější konverze do jiného API si lze napsat deduction guides, ale to už je jiné téma. V této podobě se kód přeloží s C++ 14, 17 i 20, zatímco s deduction guides by vyžadoval minimálně C++17.)

    Ještě závěrem dodám (a předejdu tak, doufám, některým komentářům), že někteří lidé mají utkvělou špatnou představu o sousloví return std::move(...); — myslí si, že něco takového nedává smysl a že by to nemělo existovat. Samozřejmě se mýlí, jak jinak; tady jsou k tomu předdrobnosti i podrobnosti.

    3.12.2020 19:17 Andrej | skóre: 51 | blog: Republic of Mordor
    Rozbalit Rozbalit vše Re: C++ shared_ptr - constrainty

    A když nad tím znova přemýšlím (což rozhodně nedělám často), čitelnější to bude bez toho nestandardního operátoru <<, který nijak neinteraguje s (kni)hovnou a jenom všeho všudy mate čtenáře (včetně mě). Takže raději třeba takto:

    #include <fstream>
    #include <iostream>
    #include <iterator>
    #include <string>
    #include <utility>
    
    namespace {
    
    template <typename C>
    struct line {
      operator const std::basic_string<C>&() const & { return str_; }
      operator std::basic_string<C>&() & { return str_; }
      operator std::basic_string<C>() && { return std::move(str_); }  // nepoužito
     private:
      std::basic_string<C> str_;
    };
    
    template <typename C>
    std::basic_istream<C>& operator >>(std::basic_istream<C> &stream,
                                       line<C> &str) {
      std::getline(stream, static_cast<std::basic_string<C>&>(str));
      return stream;
    }
    
    template<typename C>
    struct ifstream_iterable {
      ifstream_iterable(const std::string &path) : stream_{path} {}
      auto begin() { return iterator{stream_}; }
      auto end() { return iterator{}; }
     private:
      typedef std::istream_iterator<line<C>, C> iterator;
      std::basic_ifstream<C> stream_;
    };
    
    }  // namespace
    
    int main() {
      for (const std::wstring &l : ifstream_iterable<wchar_t>{"/proc/cpuinfo"})
        std::wcout << l << std::endl;
    }
    
    5.12.2020 17:07 mokere
    Rozbalit Rozbalit vše Re: C++ shared_ptr - constrainty
    Ďakujem Vám všetkým. Aj za to že ste mi opravili chybu s riadkami vs slovami. To bola moja nepozornosť. A popravde som si ju ani nevšimol.

    Každopádne MadCatX to vymyslel zaujímavo.

    Ja som chcel ale napodobniť funkciu ReadLines z .NETu https://docs.microsoft.com/en-us/dotnet/api/system.io.file.readlines?view=net-5.0 ktorá vracia IEnumerable (obsahujúca Enumerator).

    Andrej To čo ste urobili vy je presne to čo som hľadal. Za čo Vám veľmi pekne ďakujem.

    10minuteman Čo sa týka new a delete snažím sa ich používať minimálne. Ale ak pri smartpointeroch používate deleter tak sa použitiu delete nevyhnete. Veď aj smart pointery v konečnom dôsledku volajú delete.

    5.12.2020 22:17 Andrej | skóre: 51 | blog: Republic of Mordor
    Rozbalit Rozbalit vše Re: C++ shared_ptr - constrainty
    Ale ak pri smartpointeroch používate deleter tak sa použitiu delete nevyhnete.

    To je sice pravda, ale právě nadužívání dynamické alokace je u C++ poměrně častá chyba. Zrovna třeba statement delete iterator; není dobrý nápad (a kdekoho přiměje zvednout obočí), protože iterátor má být (a většinou je) malý kousek dat (něco jako 16 B, dejme tomu), který se dá a má předávat všude hodnotou. (Samozřejmě kromě případu, kdy je potřeba z více míst měnit jeden iterátor, tj. mít něco jako dvouhvězdičkový pointer.)

    Ještě bych poznamenal, jen tak pro úplnost, že příklad v dotazu by byl lepší s použitím std::unique_ptr místo std::shared_ptr. Zatímco std::unique_ptr je jednoduchý zapouzdřený pointer, který vyjadřuje exkluzivní vlastnictví a vlastní z jednoho kontextu jeden kousek dat, std::shared_ptr je složitá mašinerie s atomickým reference-countingem. Uvnitř v implementaci std::shared_ptr neukazuje přímo na data, která spravuje, nýbrž na svou vlastní dynamickou strukturu, ve které má (kromě pointeru) také atomické počítadlo referencí a pár dalších vychytávek. (Dlužno navíc dodat, v souvislosti s atomickým počítadlem, že jedna atomická instrukce může stát čas srovnatelný s řádově tisícem sčítání.) Dá se říct, že std::shared_ptr je v jistém smyslu thread-safe, byť s omezeními:

    • Několik instancí std::shared_ptr, každou z jiného vlákna, lze používat paralelně zcela bez omezení.
    • Použití jedné instance std::shared_ptr několika vlákny (například rozumně atomické přiřazení toho sdíleného pointeru) ovšem samo od sebe atomické není; k tomu slouží specializace std::atomic<std::shared_ptr<...>>.

    Zkrátka a dobře (nebo zdlouha a špatně, teď nevím),

    • kdykoliv je možné vyhnout se přímému použití pointerů, je třeba této příležitosti využít. Všechny kontejnery mají na zásobníku jenom něco velmi malého (jako třeba fixních 16 B nebo tak) a dynamickou alokaci si spravují samy.
    • kdykoliv je možné použít std::unique_ptr místo std::shared_ptr, je to jasná volba, zejména z hlediska efektivity a jednoznačnosti vlastnictví objektů. Atomický reference-counting je potřebný jenom velmi zřídka, nikoliv zhusta.
    6.12.2020 15:21 10minuteman
    Rozbalit Rozbalit vše Re: C++ shared_ptr - constrainty
    No to je prave ono: nepsat to rucne, ale nechat to za sebe resit objekty. Jasne, ze interne k new a delete treba dojde. Alokaci na halde se nejspis nevyhnes. Kdyz to ale za tebe bude resit objekt, mas pak mnohem mene starosti.

    Založit nové vláknoNahoru

    Tiskni Sdílej: Linkuj Jaggni to Vybrali.sme.sk Google Del.icio.us Facebook

    ISSN 1214-1267   www.czech-server.cz
    © 1999-2015 Nitemedia s. r. o. Všechna práva vyhrazena.