Visualizzazione dei risultati da 1 a 4 su 4
  1. #1
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    8

    Problema C++ ereditarietà e polimorfismo.

    Ciao a tutti.

    cerco di creare una lista di classi utilizzando vector dell'STL. Con il primo metodo fun<ziona, con il secondo va in crash non trovando la funzione virtuale nella tabella. Compilatore utilizzato gcc.
    Chi sa dirmi il perchè?
    includo tutti i file:

    codice:
    //// Main
    #include <iostream>
    #include "TOcc.h"
    #include "TColl.h"
    
    #include <vector>
    
    using namespace std;
    
    int main()
    {
    
        DBE dbe;
    
        cout << endl << " Metodo 1. Funziona" << endl;
    
        vector<_TOccV<DBE> *> list;
    
        _TOccV<DBE> *p;
    
        TOcc1 s1;
        p = &s1;
        list.push_back(p);
    
        TOcc2 s2;
        p = &s2;
        list.push_back(p);
    
        list[0]->Build ();
        list[1]->Build ();
    
        cout << endl << " Metodo 2. Non funziona" << endl;
    
        TColl list2;
    
        list2.BuildAll ();
    
        return 0;
    }
    codice:
    ///// TOcc.h
    #ifndef TOCC_H_INCLUDED
    #define TOCC_H_INCLUDED
    
    #include<assert.h>
    #include<vector>
    
    using namespace std;
    
    class DBE {
    
        vector<int> someData;
    
    public:
    
        DBE () {};
    
    };
    
    
    
    template <typename S>
    class _TOccV {
    
        vector< vector<int> > *_data;
        int _dataYSize;
    
        virtual void _Build (void) { cout << endl << "_TOccV::_Build" << endl; };
    
    public:
    
        _TOccV () : _dataYSize(0) { };
        _TOccV (int dataYSize) : _dataYSize(dataYSize)
        { _data = new vector< vector<int> >(dataYSize); };
        ~_TOccV ()
        { delete _data; _data = NULL; };
    
        void Push (vector<int> *v, int where) { _data[where].push_back(*v); };
        vector<int> Pop (int what) { assert(what < _data->size()); return (*_data)[what]; };
        void Build (void) { _Build (); };
    
    };
    
    
    class TOcc1 : public _TOccV<DBE> {
    
        void _Build (void) { cout << endl << "TOcc1::_Build" << endl; };
    
    public:
    
        TOcc1 () : _TOccV<DBE> (1) {};
    
    };
    
    
    class TOcc2 : public _TOccV<DBE> {
    
        void _Build (void) { cout << endl << "TOcc2::_Build" << endl; };
    
    public:
    
        TOcc2 () : _TOccV<DBE> (1) {};
    
    };
    
    #endif // TOCC_H_INCLUDED
    codice:
    /////// TColl.h
    #ifndef TCOLL_H_INCLUDED
    #define TCOLL_H_INCLUDED
    
    #include <vector>
    #include "TOcc.h"
    
    
    using namespace std;
    
    
    class TColl {
    
        vector<_TOccV<DBE> *> _list;
    
    public :
    
        TColl ();
    
        void BuildAll (void);
    
    };
    
    
    
    TColl::TColl ()
    {
    
        _TOccV<DBE> *p;
    
        TOcc1 s1;
        p = &s1;
        _list.push_back(p);
    
        TOcc2 s2;
        p = &s2;
        _list.push_back(p);
    
    };
    
    
    void TColl::BuildAll (void)
    {
        unsigned int idx;
        _TOccV<DBE> *p;
    
        for (idx = 0; idx < _list.size(); idx++)
        {
            p = _list[idx];
            p->Build ();
        }
    
    }
    
    
    #endif // TCOLL_H_INCLUDED

  2. #2
    Moderatore di Programmazione L'avatar di LeleFT
    Registrato dal
    Jun 2003
    Messaggi
    17,320

    Moderazione

    Ti consiglio di prendere visione del regolamento interno.

    1) Il titolo deve dare un'idea del contenuto della discussione. Il problema della discussione riguarda "un crash dovuto al fatto che il programma non trova la funzione virtuale nella tabella"... non un problema di "ereditarietà e polimorfismo", che molto più generale e non dice nulla del reale problema.

    2) Il codice va postato indentato e all'interno degli appositi tag CODE (vedi punto 6 del regolamento linkato).

    Correggo il titolo e sistemo il codice.


    Ciao.
    "Perchè spendere anche solo 5 dollari per un S.O., quando posso averne uno gratis e spendere quei 5 dollari per 5 bottiglie di birra?" [Jon "maddog" Hall]
    Fatti non foste a viver come bruti, ma per seguir virtute e canoscenza

  3. #3
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    8
    scusa...


    grazie!

  4. #4
    Utente di HTML.it
    Registrato dal
    Sep 2009
    Messaggi
    8

    RISOLTO!

    ok. ho trovato la soluzione.

    L'errore intanto consiste nel fatto che una volta inseriti i puntatori nel vettore gli oggetti vengono distrutti (cosa che nn capita nella versione corretta perchè sono dichiarati a livello di main () ). quindi è giusto che non venga trovata la funzione virtuale nella tabella.

    la prima soluzione, immediata è stata di dichiarare come static le due variabili s1 ed s2:

    codice:
    void TColl::init (void)
    {
    
        static TOcc1 s1;
        static TOcc1 s2;
        p = &s1
        _list2.push_back(p);
        p= &s2;
        _list2.push_back(p);
    
    };
    e in questo modo funziona. Ma avrei dovuto dichiarare come statici tutti gli elementi del vettore e non mi sembrava una soluzione elegante ma solo un gra brutto rattoppo.

    la soluzione definitiva è stato di utilizzare gli shared_ptr come segue:

    codice:
    #include <vector>
    #include <tr1/memory>   // necessario per utilizzare gli shared_ptr
    #include "TOcc.h"
    
    using namespace std;
    
    class TColl {
    
        vector<std::tr1::shared_ptr<_TOccV<DBE> > > _list2; // nuova dichiarazione del vettore
    
    public :
    
        TColl () {};
        void init (void);
        void BuildAll (void);
    
    };
    
    
    void TColl::init (void)
    {
    
        // inserzione nel vettore.
        _list2.push_back(std::tr1::shared_ptr<_TOccV<DBE> > (new TOcc1)); 
        _list2.push_back(std::tr1::shared_ptr<_TOccV<DBE> > (new TOcc2));
    
    };
    
    
    void TColl::BuildAll (void)
    {
        unsigned int idx;
    
        for (idx = 0; idx < _list2.size(); idx++)
        {
            _list2[idx]->Build(); // chiamata alla funzione virtuale
        }
    
    }
    e adesso funziona.

    Ciao a tutti

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.