Nefunguje přetypování (Qt) – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Nefunguje přetypování (Qt) – C / C++ – Fórum – Programujte.comNefunguje přetypování (Qt) – C / C++ – Fórum – Programujte.com

 

ingiraxo+15
Grafoman
20. 2. 2013   #1
-
0
-

Zdravim, mám takový problem, potrebuju pretypovat tridu na jejiho potomka a vratit tak iterator na celou kolekci, ale nejak mi to nejde :/

Přikládám ukázku jak to myslim i s komentem 

#include <QCoreApplication>
#include <QSharedPointer>
#include <QMap>
#include <QDebug>

class IUser
{
public:
    virtual void show() = 0;
};

class User : public IUser
{
public:
    User()         {}
    void show()    {}
    void destroy() {}
};

class MainClass
{
public:
    MainClass()
    {
        m_users["a"] = QSharedPointer<User>(new User);
        m_users["b"] = QSharedPointer<User>(new User);
    }

    QMapIterator<QString, QSharedPointer<IUser> > users() const
    {
        // toto nejde a tohle potrebuju nejak opravit... potrebuju ziskat iterator na tu kolekci QMap
        // nejde mi to pretypovat a pritom nechapu nejak proc, kdyz IUser je predek User
        // tipuju ze bude problem nejak v tom QSharedPointer, ale toho bych tam
        // potreboval mit, protoze je typove bezpecnej mezi vice-vlaknovou app a neni potreba pouzivat mutex
        return reinterpret_cast<QMapIterator<QString, QSharedPointer<IUser> > >(m_users.constBegin());
    }

private:
    QMap<QString, QSharedPointer<User> > m_users;
};

int main()
{
    MainClass mc;
    QMapIterator<QString, QSharedPointer<IUser> > it = mc.users();

    while (it.hasNext()) {
        it.value().data()->show();
        it.next();
    }
    return EXIT_SUCCESS;
}

diky za kazdou radu

Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
KIIV
~ Moderátor
+43
God of flame
20. 2. 2013   #2
-
0
-

neni problem v tom, ze se snazis pretypovat konstantni iterator na normalni iterator?

spis pouzit neco jako   QMap<QString, QSharedPointer<IUser> >::const_iterator   a nebude se pak ani muset pretypovavat  (ale nemam to jak otestovat)

Nahlásit jako SPAM
IP: 94.112.35.–
Program vždy dělá to co naprogramujete, ne to co chcete...
vitamin+8
Grafoman
20. 2. 2013   #3
-
0
-

S konverziou const_iteratora na nekonstantny bude problem, ale vecsi problem bude to ze niekde je pouzite User a niekde IUser (samozrejme ak to nie je len typedef).

Nahlásit jako SPAM
IP: 95.105.157.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
ingiraxo+15
Grafoman
20. 2. 2013   #4
-
0
-

#2 KIIV
tohle jsem taky zkoušel, ale píše mi to úplně to stejný 



invalid cast from type
'QMap<QString, QSharedPointer<User> >::const_iterator'
to type
'QMap<QString, QSharedPointer<IUser> >::const_iterator'

já mám spíš dojem, že u QMap to nějak nefunguje nebo dělám něco špatně, protože u QVector to funguje.. 



    // nefunguje
    QMap<QString, IUser *>::const_iterator users() const
    {
        return reinterpret_cast<QMap<QString, IUser *>::const_iterator>(m_users.constBegin());
    }

    // funguje
    QVector<IUser *>::const_iterator test() const
    {
        QVector<User *> users; // jen test
        return reinterpret_cast<QVector<IUser *>::const_iterator>(users.constBegin());
    }

EDIT: tak jsem zkousel ještě něco a asi to přes ten objekt na iteraci nejde nebo nevim - priklad 

    QVectorIterator<QSharedPointer<IUser> > test() const
    {
        QVector<QSharedPointer<User> > users; // normalni vektor
        QVectorIterator<QSharedPointer<User> > it(users); // iterator na User
        // pokus o pretypovani na IUser - nejde
        return reinterpret_cast<QVectorIterator<QSharedPointer<IUser> > >(it);
    }

Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
vitamin+8
Grafoman
20. 2. 2013   #5
-
0
-

1. reinterpred_cast funguje len na integre a pointre.

2. Aj ked je IUser bazou User, tak templaty to ignoruju:

struct B{};
struct D : B{};

template <class T>
struct X{};

int main(){
	B* b;
	D* d;

	b = d;	//OK
	
	X<B>* bx;
	X<D>* dx;

	bx = dx;  //chyba!!!
}

}
Nahlásit jako SPAM
IP: 95.105.157.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
ingiraxo+15
Grafoman
20. 2. 2013   #6
-
0
-

#5 vitamin
však jistě, ten příklad co si uvedl je jasný že nejde, ale můžeš to explicitně přetypovat nebo použít nějakej caster, třeba reinterpred_cast a bude ti to fungovat.. kór když to B je předek D

můj problém spíš je, že QVectorIterator nebo QMapIterator jsou postavený na nějakým zvláštním objektu, zkoušel jsem i qobject_cast a stejně mi to nevzalo :/

Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
vitamin+8
Grafoman
21. 2. 2013   #7
-
0
-

invalid cast from type
'QMap<QString, QSharedPointer<User> >::const_iterator'
to type
'QMap<QString, QSharedPointer<IUser> >::const_iterator'

Nahlásit jako SPAM
IP: 95.105.157.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
ingiraxo+15
Grafoman
21. 2. 2013   #8
-
0
-

#7 vitamin
to je ale u QMapy... u ní nechápu proč to nejde.. když místo toho hodim QVector, tak není problém a funguje

to přetypování User na IUser v tom nehraje roli, když User dědí od IUser

ukázka 

    // FUNGUJE
    QVector<IUser *>::const_iterator users1() const
    {
        QVector<User *> arr;
        return reinterpret_cast<QVector<IUser *>::const_iterator>(arr.constBegin());
    }

    // FUNGUJE
    QVector<QSharedPointer<IUser> >::const_iterator users2() const
    {
        QVector<QSharedPointer<User> > arr;
        return reinterpret_cast<QVector<QSharedPointer<IUser> >::const_iterator>(arr.constBegin());
    }

    // FUNGUJE
    QVector<QPair<QString, QSharedPointer<IUser> > >::const_iterator users3() const
    {
        QVector<QPair<QString, QSharedPointer<User> > > arr;
        return reinterpret_cast<QVector<QPair<QString, QSharedPointer<IUser> > >::const_iterator>(arr.constBegin());
    }

    // NEFUNGUJE !! (asi kvuli QMap nebo nevim...)
    QMap<QString, QSharedPointer<IUser> >::const_iterator users4() const
    {
        QMap<QString, QSharedPointer<User> > arr;
        return reinterpret_cast<QMap<QString, QSharedPointer<IUser> >::const_iterator>(arr.constBegin());
    }
Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
vitamin+8
Grafoman
21. 2. 2013   #9
-
0
-
Nahlásit jako SPAM
IP: 95.105.157.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
ingiraxo+15
Grafoman
21. 2. 2013   #10
-
0
-

Tak už jsem to vyřešil jinak,takže pošlu řešení... akorát mě trochu štve ten výpis, protože se mi nepodařilo jinak ošetřit zastavení cyklu než přes ten SharedPointer (kdyby tam nebyl, tak by byl problém) =D 

class IUser
{
public:
    virtual void show() = 0;
};

class User : public IUser
{
public:
    User()         {}
    void show()    {}
    void destroy() {}
};

class MainClass
{
public:
    MainClass()
    {
        m_users.push_back(QPair<QString, QSharedPointer<User> >("a", QSharedPointer<User>(new User)));
        m_users.push_back(QPair<QString, QSharedPointer<User> >("b", QSharedPointer<User>(new User)));
        m_users.push_back(QPair<QString, QSharedPointer<User> >("c", QSharedPointer<User>(new User)));
    }

    QVector<QPair<QString, QSharedPointer<IUser> > >::const_iterator users() const
    {
        return reinterpret_cast<QVector<QPair<QString, QSharedPointer<IUser> > >::const_iterator>(m_users.constBegin());
    }

private:
    QVector<QPair<QString, QSharedPointer<User> > > m_users;
};

int main()
{
    MainClass mc;
    QVector<QPair<QString, QSharedPointer<IUser> > >::const_iterator it = mc.users();

    while (!it->second.isNull())
    {
        qDebug() << it->first;
        ++it;
    }
    return EXIT_SUCCESS;
}
Nahlásit jako SPAM
IP: 213.168.183.–
Moje aplikace: http://ophite.cz
Tutoriály na: C#
vitamin+8
Grafoman
21. 2. 2013   #11
-
0
-

spravnejsie by si si mal spravyt vlastny iterator, hlavne do buducna ak zmenis mapu za nieco ine tak sa to neotkne zvysku kodu:

#include <QCoreApplication>
#include <QSharedPointer>
#include <QMap>
#include <QDebug>

class IUser
{
public:
    virtual void show() = 0;
};

class User : public IUser
{
public:
    User()         {}
    void show()    {}
    void destroy() {}
};

class MainClass
{
public:
    MainClass()
    {
        m_users["a"] = QSharedPointer<User>(new User);
        m_users["b"] = QSharedPointer<User>(new User);
    }
    class iterator :  public std::iterator<std::input_iterator_tag, User>{
        typedef QMap<QString, QSharedPointer<User> >::const_iterator map_iter_type;
        map_iter_type it;
    public:
        iterator(map_iter_type it):it(it){}
        iterator(const iterator&)=default;

        User* operator->(){return it->data();}
        User& operator*(){return *it->data();}

        bool operator==(const iterator& i)const{return it == i.it;}
        bool operator!=(const iterator& i)const{return it != i.it;}
        void operator++(){++it;}
        void operator++(int){it++;}
        void operator--(){--it;}
        void operator--(int){it--;}

    };
    inline iterator begin(){return iterator(m_users.begin());}
    inline iterator end(){return iterator(m_users.end());}

private:
    QMap<QString, QSharedPointer<User> > m_users;
};


int main()
{
    MainClass mc;
    //v c++11:   for(auto& u : mc)u.show();
    for(MainClass::iterator i = mc.begin(); i != mc.end(); ++i){
       i->show();
    }
    return EXIT_SUCCESS;
}
Nahlásit jako SPAM
IP: 95.105.157.–
obfuscate: "The cruel god Malloc will strike you down. "
ZMeson: "That's the C god. C++ has a new god. "
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 96 hostů

Podobná vlákna

Pretypovani v C — založil TuTi_fruTi

Přetypování. — založil jisla

C# přetypování — založil ondra

Přetypování — založil Pavel Synek

Přetypování — založil Keyzio

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý