[C++] Jak zjistim, zda de o ukazatel?

C++, C#, Visual Basic, Delphi, Perl a ostatní

Moderátor: Moderátoři Živě.cz

Odeslat příspěvekod root 9. 6. 2006 22:50

Hello, guyz.

Kód: Vybrat vše
/***************************************************************************
*   Copyright (C) 2006 by tulpik   *
*   gimperek@gmail.com   *
*                                                                         *
*   This program is free software; you can redistribute it and/or modify  *
*   it under the terms of the GNU General Public License as published by  *
*   the Free Software Foundation; either version 2 of the License, or     *
*   (at your option) any later version.                                   *
*                                                                         *
*   This program is distributed in the hope that it will be useful,       *
*   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
*   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
*   GNU General Public License for more details.                          *
*                                                                         *
*   You should have received a copy of the GNU General Public License     *
*   along with this program; if not, write to the                         *
*   Free Software Foundation, Inc.,                                       *
*   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
***************************************************************************/

#ifndef TUBOTHOOK_T_H
#define TUBOTHOOK_T_H

#include <string>
#include <vector>
#include <map>

using namespace std;

namespace TuBot {

    /**
     @short struktura hooku, udava pravidla kdy hookovat.
     @author tulpik
    */
    struct Hook_t {
        /** @param host     = pair host + nick */
        pair<string, string>    host;
        /** @param body     = definovany pole tela */
        vector<string>          body;
        /** @param data     = definovana msg */
        string msg;
        inline bool operator < (const Hook_t& h) const {
            if( body == h.body )
                if( msg == h.msg )
                    if( host.first == h.host.first )
                        if( host.second == h.host.second )
                            return true;
            return false;
        };
    };

    /**
     @short Zakladni hook handler, podle classy hookuje
     @param template = hook object
     @author tulpik
    */
    template<class T> class TuBotHook_t {

    /**
     @param HookHandle  = ukazatel na clena tridy T
     @param Hooks       = datovej typ pro mapu uchovavajici handly
     @param hooks       = mapa uchovavjici hooky (handly)
    */
    typedef int (T::*HookHandle)(Hook_t*, TuBotHook_t<T>* );
    typedef multimap< Hook_t*, HookHandle > Hooks;

    Hooks hooks;

    public:
        /**
         @short konstruktor
         @author tulpik
        */
        TuBotHook_t( );

        /**
         @short destruktor
         @author tulpik
        */
        ~TuBotHook_t( );

        /**
         @short Prida hook na text
         @param hook    = akce na kterou se ma hookovat (volat fce)
         @param fce     = ukazatel na clena tridy T
         @author tulpik
        */
        void addHook( Hook_t hook, HookHandle fce );

        /**
         @short Smaze hook, pokud existuje
         @param hook    = hook na ktery je nahookovano
         @param return  = pokud se to povede tak 1, jinak 0
         @author tulpik
        */
        int delHook( Hook_t hook );

        /**
         @short Pokusi se najit hook na text, pokud existuje vola hook
         @param hook    = text na ktery se ma hook volat
         @author tulpik
        */
        void call( Hook_t hook );
    };

    template<class T> TuBotHook_t<T>::TuBotHook_t( ) {

    }

    template<class T> TuBotHook_t<T>::~TuBotHook_t( ) {

    }

    template<class T> void TuBotHook_t<T>::addHook( Hook_t hook, HookHandle fce ) {
        // hodim do seznamu hooku, text a funkci, ktera se ma na nej volat
        hooks.insert( make_pair( &hook, fce ) );
    }

    template<class T> void TuBotHook_t<T>::call( Hook_t hook ) {
        // definuju datovej typ
        T Hook;
        // definuju si iterator
        typename Hooks::iterator HookIt;
        // najdu si vsechny hodnoty klice, kterym je text
        for( HookIt = hooks.lower_bound( &hook );
            HookIt != hooks.upper_bound( &hook ); ++HookIt ) {
            // zavolam hook
            (Hook.*HookIt->second)( &hook, this );

        }
    }

    template<class T> int TuBotHook_t<T>::delHook( Hook_t hook ) {
        // definuju datovej typ
        T Hook;
        typename Hooks::iterator Test;
        // definuju iterator
        Test = hooks.find( hook );
        // pokusim se najit text hooku
        if( Test != hooks.end( ) ) {
            // kdyz ho najdu, tak ho smazu
            hooks.erase( hook );
        // povedlo se smazat hook, vratim 1
        return 1;
        }
    // hook nebyl smazanej, tak vratim 0
    return 0;
    }
}

#endif


Potreboval bych nejak zjistit zda byl se sablonou predanej ukazatel a podle toho volat bud .* nebo ->*. Dik

Upraveno pro cestinu.

//christian: poupraven název threadu
root
Junior
Uživatelský avatar

Odeslat příspěvekod root 5. 9. 2006 10:34

Hm? Nikdo nevi? :roll:
root
Junior
Uživatelský avatar

Odeslat příspěvekod Ares952 5. 9. 2006 10:46

rekl bych, ze v c++ pujde zjistit pouze to, zda jdea o konkretni typ, ne obecne ze se jedna o ukazatel
Naděje je motorem duše
Ares952
Mírně pokročilý
Uživatelský avatar

Odeslat příspěvekod singleton 5. 9. 2006 16:45

to myslis tento kod vazne? par veci sa mi tam nezda... uvediem jednu z mnohych:
Kód: Vybrat vše
inline bool operator < (const Hook_t& h) const {
    if( body == h.body )
        if( msg == h.msg )
            if( host.first == h.host.first )
                if( host.second == h.host.second )
                    return true;
    return false;
};


to vyzera byt skor na operator== a nie na operator <
singleton
Junior

Odeslat příspěvekod Benjamin 6. 9. 2006 09:06

2 singelton: To vis. Kod vydany pod GNU... Co bys cekal :P :D :D
Umělá inteligence není soupeř pro přirozenou hloupost.
Benjamin
Junior
Uživatelský avatar

Odeslat příspěvekod root 6. 9. 2006 09:42

Tak docista to neni operator ==, prostuduj si std::multimap.

Navic, ten kod je silne neoptimalizovanej, uz zastaralej. slouzici jako ukazka, bez toho operatoru proste std::multimap::{lower,upper}_bound fungovat nebude :P
root
Junior
Uživatelský avatar

Odeslat příspěvekod Nargon 6. 9. 2006 09:51

A co vy vite, treba prave chce aby operator "<" byl pouzivan jako "=="
Desktop: Ryzen 7 1800X (3.95GHz, 1.35V), Asus Crosshair VI Hero, 16GB DDR4 Ram (3200MHz), 128GB SSD + 3TB HDD, Nvidia GTX 1080
Notebook: Asus UL50VT 15.6" (SU7300@1.7GHz, 4GB ram, 500GB HDD, Intel GMA 4500MHD + nVidia G210M, dlouha vydrz cca 7+ hod)
Nargon
Moderátor

Odeslat příspěvekod root 6. 9. 2006 10:06

To je tezky, clovek kterej o tom _nic_ nevi, odpovida naprostym balastem nesmylu.. Hold ceske diskuze + zive.cz :(
root
Junior
Uživatelský avatar

Odeslat příspěvekod singleton 6. 9. 2006 16:47

tak to je pravda, na tomto fore je plno totalnych cvokov; ale kvoli tym normalnym prispevkom sa tu da zistit vela dolezitych informacii.

co sa tyka uvedeneho kodu tak mi je z neho na grcanie. fakt otras. napriek tomu vas ubezpecujem, ze sa k osobnym utokom neznizim. a na taketo blbosti vam uz taktiez nebudem odpovedat.
singleton
Junior

Odeslat příspěvekod root 6. 9. 2006 17:20

Tak mi prosim te, ukaz nejakej tvuj kod, ja opravdu nevim co je na nem otresnyho, je tam asi 50+- radku kodu, zbytek komentare, rad bych videl neco z tve prace kdyz snizujes druhe.. Ukaz mi nejaky tvuj kod at muzem porovnat..
root
Junior
Uživatelský avatar

Odeslat příspěvekod Kyosuke 6. 9. 2006 23:23

Nejsem C++kař, ale není lepší místo tohohle nesmyslu:

Kód: Vybrat vše
        inline bool operator < (const Hook_t& h) const {
            if( body == h.body )
                if( msg == h.msg )
                    if( host.first == h.host.first )
                        if( host.second == h.host.second )
                            return true;
            return false;
        };


napsat prostě

Kód: Vybrat vše
        inline bool operator < (const Hook_t& h) const {
            return ((body == h.body) &&
                    (msg == h.msg) &&
                    (host.first == h.host.first) &&
                    (host.second == h.host.second));
        };


?

Mně tohle připomíná ty prasárny z thedailywtf.com, tam se taky čas od času objevují konstrukce typu "if A return true else return false", nad kterými zůstává rozum stát. Tohle s lidma dělá Cčko. :-D Doporučuju jako terapii 500 mg Lispu třikrát denně do vyléčení. :-D
Kyosuke
Junior

Odeslat příspěvekod root 7. 9. 2006 09:56

Dalsi takovej. Ja se _NEPTAL_ na konstrukci opratoru ve strukture, chapes to? Proc mi odpovidas na neco, co nema s threadem nic spolecnyho, navic to co jsi ty napsal, je na stejnej pocet radku a dovolim si tvrdit, ze i na stejnej pocet znaku, takze: proc by to melo bejt lepsi? Navic je to jenom "exampl". _OMG_
root
Junior
Uživatelský avatar

Odeslat příspěvekod Kyosuke 7. 9. 2006 11:21

root píše:Proc mi odpovidas na neco, co nema s threadem nic spolecnyho

Protože:

quote]ja opravdu nevim co je na nem otresnyho


Prostě jen namátkový příklad, abys „opravdu věděl“. :-D Nejde ani tak o počet řádků, jako spíš o logiku věci. (BTW, jestli měříš složitost jenom počtem řádků, proč neprogramuješ v Perlu – v něm je hromada věcí velice krátká.) Pokud nechápeš, proč je to blbost, je mi jasné, že další vysvětlování by bylo zbytečné – prostě Ti mozek pracuje v tomhle směru jinak, než většině lidí. Dokud to funguje a kompilátory eliminují mrtvou sémantiku, vyjde to nastejno, budiž.

Jinak teda ta konstrukce (Hook.*HookIt->second)(&hook, this) je vzhledem ke zbytku té šablony natolik zavádějící a neprůhledná, že se nedivím, že se v tom očividně nikdo nevyzná. :-D (Mně teda "T Hook;" přijde jako definice a (při průchodu) inicializace proměnné s názvem Hook, přitom nad tím je komentář „definuju datovej typ“ – ? Ale v porovnání s používáním ukazatelů na členy je to jen hnída. Není třeba být geek za každou cenu každý den, kdy píšeš nějaký C++ kód. ;-))

Každopádně šablony dělají to, co dělají, těžko od nich očekávat nějakou závratnou inteligenci. Buď si to rozhodnutí vyfaktoruj v čase návrhu nebo to takhle neřeš. Prakticky jakékoli řešení bude jednodušší.
Kyosuke
Junior

Odeslat příspěvekod root 7. 9. 2006 13:46

Ok, konecim tento thread, abych rekl pravdu uz kdyz jsem pokladal tento dotaz, vedel jsem ze to neni mozne zjitit. Staci? Jen sem chtel videt ty placaniny co tu kdo napise.

Jinak k te structure - je to EXAMPLE( ukazka ), neni finalni, tudis je jedno jestli tam bude retrun (neco && necojinyho) nebo ...

Proste demence :)
root
Junior
Uživatelský avatar

Odeslat příspěvekod Kyosuke 7. 9. 2006 14:39

A co jsi čekal, když se tu tasíš s member pointery? :-D Takovou šílenou konstrukci bych si nechal do vyšší dívčí… :-B Jejich odstraněním se problém eliminuje sám a není třeba řešit závislost šablony na datovém typu (což je samo o sobě popřením genericity). :lol:
Kyosuke
Junior

Odeslat příspěvekod root 7. 9. 2006 17:07

Jojo, ale pointer-to-member + samblony proste ruluje :D Uz jsem tomu nasel i uplatneni :-B
root
Junior
Uživatelský avatar

Odeslat příspěvekod singleton 7. 9. 2006 17:31

2root: myslel som si, ze sa tu uz neozvem, ale ja ta naozaj nechapem. ved ludia ti nechcu zle poradit a ty ich urazas.

Neda mi to a poukazem na niekolko chybnych veci v kode:

typ Hooks je definovany ako:
typedef multimap< Hook_t*, HookHandle > Hooks;

1.) funkcia:
addHook( Hook_t hook, HookHandle fce );
vlozi do map (Hooks) adresu automatickej premennej, co skonci na "access violation..."

2.) funkcia:
delHook( Hook_t hook );
vyhladava pomocou hooks.find(hook), co je zle, pretoze v map (Hooks) mas ako kluce ulozene adresy (Hook_t *)

3.) funkcie call a delHook:
typename sa pouziva v deklaracii sablony, inde sa pouziva typedef

4.)funkcia call:
vo for mas chybu, premenna HookIt nebola definovana:
for( HookIt = hooks.lower_bound( &hook ); ...

5.)funkcia call:
vytvaras typ T s impicitnym konstruktorom a potom volas jeho procedury -- na taketo nieco sa hodi skor staticka funkcia, nie clenska

6.) operator <:
ked chces implementovat operator < za kazdu cenu (nezalezi ti na usporiadani), aby ti fungoval map, tak aky vyznam ma vracat rovnost objektov? lepsie by bolo vracat konstatnu hodnotu alebo porovnavat iba cast objektu

7.) funckia delHook:
ak vymaze prvok, vrati 1, inak vrati 0 -- v takychto pripadoch by sa mal pouzivat bool; respektive vracat pocet vymazanych prvkov

8.) funkcia delHook:
prvky z multimap si mal mazat pomocou overloadu funkcie:
size_type erase(const key_type& _Key);
a nie najprv vyhladat, potom ulozit iterator, potom otestovat iterator a nakoniec funkcia erase

9.) aspon ked davas na forum svoj zdrojak, tak si prosim ta vymaz tie riadky komentaru, lebo clovek zaspi skor ako si docita tych par riadkov kodu :)

Ostava mi len dufat, ze moju kritiku primes konstruktivne a ze mi za odmenu nebudes nadavat do dementov a ze nic neviem.
singleton
Junior

Odeslat příspěvekod Kyosuke 8. 9. 2006 17:25

root píše:Jojo, ale pointer-to-member + samblony proste ruluje :D Uz jsem tomu nasel i uplatneni :-B


A teď se ještě naučit rozdíl mezi stackem a heapem a budeš maximální king… :mrgreen: :mrgreen:
Kyosuke
Junior

Odeslat příspěvekod Kyosuke 8. 9. 2006 23:12

singleton píše:4.)funkcia call:
vo for mas chybu, premenna HookIt nebola definovana:
for( HookIt = hooks.lower_bound( &hook ); ...


Já si ještě kopnu do mrtvoly: Multimapa chce referenci na objekt. On jí předá (jak píšeš v 1)) pointer, takže multimapa ukládá jako klíče pointery na automatické proměnné. A ve funkci call jiný pointer na objekt na stacku použije jako klíč. Jak má zaručeno, že odpovídající pointer v té mapě vůbec bude? Leda, že by funkce call a addHook měly stejný paměťový layout parametrů a lokálních proměnných, pokud jde o hook předávaný na zásobníku, a byly zavolány ve stejné úrovni zanoření – nebo prostě tak, aby call měl svůj parametr hook na zásobníku stejném místě v paměti jako addHook, který ho přidal…ale kde je v tom smysl (pominu-li, že tohle si každý kompilátor zorganizuje sám)? :roll:
Kyosuke
Junior

Odeslat příspěvekod singleton 9. 9. 2006 11:35

to je tak, ked taky expert zacne programovat :D
a ze povedal nieco zle na diskusiu na zive.cz -- tak hanenie od neho nas rozhodne neurazi :lol:
singleton
Junior

Odeslat příspěvekod Kyosuke 9. 9. 2006 14:30

No, dal jsem nakouknout nejlepším C++kařům, co znám a které velice respektuju, a pak se jen bavil… :lol: Já radši půjdu zase tvrdě dřít toho Eckela, Alexandrescua a Suttera, abych jednou nedopadl stejně. :-)
Kyosuke
Junior


Kdo je online

Uživatelé procházející toto fórum: Žádní registrovaní uživatelé a 0 návštevníků