Visualizzazione dei risultati da 1 a 10 su 10
  1. #1
    Utente di HTML.it
    Registrato dal
    Jun 2003
    Messaggi
    4,826

    [c++]variabile membro public static

    ciao.
    ho la seguente classe:
    [code]
    class CRelAssociatedMaterial
    : public CBaseIfc
    {
    public:
    CRelAssociatedMaterial(void);
    virtual ~CRelAssociatedMaterial(void);
    bool GetData(wstring tag, wstring value, int pos, CBaseIfc** pIfcValue);
    void SetData( CBaseIfc* pData, int pos);
    CMaterialLayerSetUsage* GetMaterialLayerSetUsage();
    wstring GetType();
    static std::map<wstring, CMaterialLayerSetUsage* > m_mapMaterialsIfc;
    private:
    bool m_bHasData;
    wstring m_Name;
    wstring m_Description;
    CMaterialLayerSetUsage* m_materialLayerSetUsage;
    };

    [code]

    ho dichiarato(non so se è un errore) la variabile membro:

    static std::map<wstring, CMaterialLayerSetUsage* > m_mapMaterialsIfc;

    all interno del .cpp relativo assegno gli elementi con :

    if(pData->GetType().compare(L"IfcMaterialLayerSetUsage")==0 )
    CRelAssociatedMaterial::m_mapMaterialsIfc[pData->GetID()] = elemento;

    ma quando compilo il progetto mi da quest errore che se tolgo quest ultima linea scompare

    questo è l'errore indecifrabile:
    CmpImportApi error LNK2001: unresolved external symbol "public: static class std::map<class std::basic_string<unsigned short,struct std::char_traits<unsigned short>,class std::allocator<unsigned short> >,class CMaterialLayerSetUsage *,struct std::less<class std::basic_string<unsigned short,struct std::char_traits<unsigned short>,class std::allocator<unsigned short> > >,class std::allocator<struct std:air<class std::basic_string<unsigned short,struct std::char_traits<unsigned short>,class std::allocator<unsigned short> > const ,class CMaterialLayerSetUsage *> > > CRelAssociatedMaterial::m_mapMaterialsIfc" (?m_mapMaterialsIfc@CRelAssociatedMaterial@@2V?$ma p@V?$basic_string@GU?$char_traits@G@std@@V?$alloca tor@G@2@@std@@PAVCMaterialLayerSetUsage@@U?$less@V ?$basic_string@GU?$char_traits@G@std@@V?$allocator @G@2@@std@@@2@V?$allocator@U?$pair@$$CBV?$basic_st ring@GU?$char_traits@G@std@@V?$allocator@G@2@@std@ @PAVCMaterialLayerSetUsage@@@std@@@2@@std@@A)


    perchè?
    ho letto che le variabili statiche hanno come scope il file in cuisono dichiarate , ci sono degli svantaggi ad utilizzare una variabile static globale?
    come mi consigliate di fare?
    grazie.

  2. #2
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Nel .cpp devi mettere:
    codice:
    std::map<wstring, CMaterialLayerSetUsage* > CBaseIfc::m_mapMaterialsIfc;
    e basta. Sono i metodi della classe che devono riempire la mappa.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  3. #3
    variabile globale static, variabile membro static, e variabile locale static sono tre cose differenti.
    In particolare venendo al tuo problema, le variabili membro static oltreché dichiarate, vanno anche definite (tipicamente nel *.cpp).
    Ad esempio nel tuo caso, nel *.cpp devi definire:
    codice:
    std::map<wstring, CMaterialLayerSetUsage* > CRelAssociatedMaterial::m_mapMaterialsIfc;
    ti consiglio di usare un prefisso differente per le variabili membro static da quelle non static.
    Ad esempio io uso fg per le prime e f per le seconde (in cui la g serve ad enfatizzare che ha vita globale).
    Tu che ne so potresti usare ad esempio in modo analogo un "mg".
    ;-)

  4. #4
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Stasera sono cotto: ho messo la classe sbagliata.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  5. #5
    Utente di HTML.it
    Registrato dal
    Jun 2003
    Messaggi
    4,826
    grazie , gentili come sempre .
    Se avete tempo , quando mi consigliate di utilizzare queste variabili statiche e quando no?
    Grazie.

  6. #6
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Si usano quando la stessa variabile dev'essere condivisa tra più oggetti della stessa classe, oppure da oggetti derivati da quella classe.
    Ricorda che se una varibile è dichiarata static, ne esiste una e una sola per tutti.
    In caso di template, però, questo è vero solo per i template che specificano lo stesso parametro. Se due template sono istanziati con parametro diverso, verranno generate due distinte varibili static, una per template.

    In caso di multihreading una variabile static è da manipolare con cautela.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  7. #7
    Utente di HTML.it
    Registrato dal
    Jun 2003
    Messaggi
    4,826
    Allora , vi chiedo un ultima cosa:

    codice:
    vector<CRelContainedInSpatialStructure*> m_GraphicsElements;
    .
    .
    .
            if(localName.compare(L"IfcLocalPlacement")==0)
    		pElement = new CLocalPlacementIfc();
    	if(localName.compare(L"IfcSlab")==0)
    		pElement = new CSlabIfc();
    
    	if(localName.compare(L"IfcRelContainedInSpatialStructure")==0)
    	{
    		CRelContainedInSpatialStructure* pGraphicsElement = new CRelContainedInSpatialStructure();
    		pElement = pGraphicsElement;
    		m_GraphicsElements.push_back(pGraphicsElement);
    		
    		
    	}
    .
    .
    .
    popolo pElement
    Ho creato un metodo di parsing che scorre l'xml e carica i dati di ciascuna classe corrispondente ad un nodo xml con nome localname.
    CRelContainedInSpatialStructure è la classe padre nell xml che contiene tutti gli altri elementi e posso averne piu di una , infatti alla fine mi trovo il vector m_GraphicsElements popolato con tutti i padri di tutte le classi.
    In pratica ho fatto in modo che quando trovo l'elemento IfcRelContainedInSpatialStructure setto l'indirizzo di pGraphicsElement uguale a quello di pelement e successivamente a pelement si aggiungono a grappolo tutti gli altri elementi e mi trovero nel vector (per via dell indirizzo uguale)tutta la struttura degli elementi che mi interessano).
    Alla fine creo un metodo get per "andare a prendere" il vector dalla classe che ha instanziato la classe di parsing.
    Adesso dovrei fare la stessa cosa creando una mappa accessibile all esterno con un metodo get che contenga gli oggetti CRelAssociatesMaterial indicizzati pero' per una proprietà interna a questa classe diciamo IDWall che pero' non posseggo subito , ma alla fine del parsing di quella classe.
    Posso utilizzare la stessa tecnica dell' indirizzo uguale?
    Associando alla creazione l'indirizzo in modo che poi successivamente modificando(popolando) lo stesso indirizzo mi ritrovo una mappa indizizzata per iDWall?
    come mi consigliate di fare?
    L'alternativa a questo casino è ciclare tutte le classi e controllare che la proprieta IDWall sia la stessa tra qella ceercata e quella presente e ritornare l'oggetto .
    Questo renderebbe tutto piu' semplice ,ma molto piu lento?
    forse pero' il gioco della mappa non vale la candela.
    Grazie.

  8. #8
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Se ti serve che sia comune a tutte le classi: si. L'unico prerequisto è che la mappa esista ( sia allocata ) nel momento in cui di devi accedere.

    Edit.
    Ma questo idWall è univoco per classe?
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

  9. #9
    Utente di HTML.it
    Registrato dal
    Jun 2003
    Messaggi
    4,826
    ciao.

    no, idwall è univoco per oggetto(istanza) posso avere molti oggetti instanziati da CWall(la classe con idwall)che hanno pero tutti idwall diverso che li identifica univocamente.
    L'oggetto in cui il Wall è contenuto si chiama CRelAssociatesMaterial:
    codice:
    xml:
    <IfcRelAssociatesMaterial id="i12864">
    	<RelatedObjects ex:cType="set">
            	<IfcWallStandardCase pos="0" xsi:nil="true" ref="i12801"/>
    	</RelatedObjects>
    	<RelatingMaterial>
    	   <IfcMaterial xsi:nil="true" ref="i12787"/>
    	</RelatingMaterial>
    </IfcRelAssociatesMaterial>
    classe
    codice:
    Class CRelAssociatesMaterial
    {
    .
    .
    .
    string* IDWall(in questo caso "i12801")
    string* idMaterial(in questo caso "i12787")
    CWall* m_wallstandardcase;
    CMaterial* material;
    }
    per ogni volta che ho instanziato la classe CRelAssociatesMaterial e popolato con i dati presenti nell xml ho gli elementi diversi.
    Per ogni wallstandardcase(è il nome corretto di wall) ho una classe CRelAssociatesMaterial che mi associa il wall al materiale.
    Quindi la mappa statica è la soluzione migliore secondo te?
    Il problema è che quando istanzio la classe CRelAssociatesMaterial non ho ancora l'idwall e l'idMaterial , e la soluzione che ho pensato è quella di settare l'indirizzo del puntatore idmaterial (ad esempio) all' indirizzo di una variabile e usare quest indirizzo come indice nella mappa in modo che quando l'indirizzo verra' popolato avro anche nella mappa il cambiamento.
    Il problema per cui non riesco a fare questo giochetto , è che l'indice della mappa è un intero e non un puntatore ad intero e voglio che rimanga un intero perchè devo andare a pescare dall' idwall che è appunto un int.
    Valutando le possibilita' esiste anche ciclare tutte gli oggetti in un vector che contiene delle istanze di CRelAssociatesMaterial e controllare che il suo idwall sia uguale a quello da cercare , se trovo l'id ritorno , non mi sembra cosi' lento per 1000/2000 elementi.
    cosa ne pensi?
    grazie.

  10. #10
    Utente di HTML.it L'avatar di shodan
    Registrato dal
    Jun 2001
    Messaggi
    2,381
    Il problema è che quando istanzio la classe CRelAssociatesMaterial non ho ancora l'idwall e l'idMaterial
    Però li ricavi subito dopo, vero?
    In questo caso, puoi memorizzare IDWall nella classe e quando hai ricavato anche il materiale relativo, fai l'inserimento nella mappa usando IDWall come chiave e idmaterial come valore.
    This code and information is provided "as is" without warranty of any kind, either expressed
    or implied, including but not limited to the implied warranties of merchantability and/or
    fitness for a particular purpose.

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 © 2026 vBulletin Solutions, Inc. All rights reserved.