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

    [c++]template wrapper, libreria xsd e costruttore di default

    ciao.
    Sto utilizzando la libreria Code Synthesis http://www.codesynthesis.com/ , un xsd open source che genera classi c++ da un xsd e per farla breve fa tutto quello che fa l'xsd.exe di microsoft, solo che lo fa per il c++.
    ora , vorrei creare un wrapper attorno a tutte le classi per avere una o piu funzioni membro oltre a quelle che gia ci sono, in questo caso la
    void print().
    codice:
     template < class T >
    	class pippo : public T
    	{ 
    	public:		
    	pippo (const ::xercesc::DOMElement& e,
                      ::xml_schema::flags f = 0,
    				  ::xml_schema::container* c = 0){};
    
        pippo (const T& x,
                      ::xml_schema::flags f = 0,
    				  ::xml_schema::container* c = 0){};
    		void print(){};
    	};
    sempre tramite command line posso instanziare il template in modo da generare questo codice per tutte le classi col tipo xsd generato base_XXX:
    codice:
    typedef xml_schema::pippo<base_contact> contact;
    dove base_contact è il tipo generato dall xsd come classe c++.
    Ora, farlo per tutte le classi è facile, perchè posso usare le espressioni reglari per instanziare tutte le classi che voglio e ho moltissime classi.

    veniamo alle note dolenti: se genero ottengo:

    Error 1 error C2512: 'contacts::base_contact' : no appropriate default constructor available c:\ifc\codesynthesis xsd 3.3\examples\cxx\tree\custom\contacts\ifc\contacts .hxx 213 contacts 1

    quando si eredita non si ereditano anche i costruttori?
    inoltre non posso permettermi di inserire in tutte le classi un costruttore di default, e poi perchè normalmente funziona senza il costruttore di default?

    come posso risolvere?

    grazie.

  2. #2
    Utente di HTML.it
    Registrato dal
    Jun 2003
    Messaggi
    4,826
    ho risolto richiamando dai costruttori derivati i costruttori della classe base.
    Non capisco pero bene il perchè, sono solo andato a "naso".

    qualcuno mi puo colmare la lacuna?


    grazie.

  3. #3

    Re: [c++]template wrapper, libreria xsd e costruttore di default

    Originariamente inviato da giuseppe500
    quando si eredita non si ereditano anche i costruttori?
    No, devi ricrearli esplicitamente ed eventualmente chiamare i corrispondenti costruttori della classe base.
    inoltre non posso permettermi di inserire in tutte le classi un costruttore di default, e poi perchè normalmente funziona senza il costruttore di default?
    Probabilmente perché "normalmente" erediti da classi che hanno un costruttore di default, per cui non è necessario richiamare esplicitamente un costruttore delle classi base.
    Amaro C++, il gusto pieno dell'undefined behavior.

  4. #4
    Utente di HTML.it
    Registrato dal
    Jun 2003
    Messaggi
    4,826
    ciao.
    Ho un altro problema coi costruttori sullo stesso procedimento:
    a volte capita che una classe abbia i costruttori più disparati che servono per creare l'oggetto ad es:
    codice:
     base_IfcBuildingElement::
          base_IfcBuildingElement ()
          : ::ifcXML::IFC2x3::FINAL::IfcElement ()
          {
          }
    
          base_IfcBuildingElement::
          base_IfcBuildingElement (const GlobalId_type& GlobalId,
                                   const OwnerHistory_type& OwnerHistory)
          : ::ifcXML::IFC2x3::FINAL::IfcElement (GlobalId,
                                                 OwnerHistory)
          {
          }
    
          base_IfcBuildingElement::
          base_IfcBuildingElement (const GlobalId_type& GlobalId,
                                   ::std::auto_ptr< OwnerHistory_type >& OwnerHistory)
          : ::ifcXML::IFC2x3::FINAL::IfcElement (GlobalId,
                                                 OwnerHistory)
          {
          }
    
          base_IfcBuildingElement::
          base_IfcBuildingElement (const base_IfcBuildingElement& x,
                                   ::xml_schema::flags f,
                                   ::xml_schema::container* c)
          : ::ifcXML::IFC2x3::FINAL::IfcElement (x, f, c)
          {
          }
    
          base_IfcBuildingElement* base_IfcBuildingElement::
          _clone (::xml_schema::flags f,
                  ::xml_schema::container* c) const
          {
            return new class base_IfcBuildingElement (*this, f, c);
          }
    
          base_IfcBuildingElement::
          ~base_IfcBuildingElement ()
          {
          }
    questo costruttore e cosi altri:
    codice:
          base_IfcBuildingElement::
          base_IfcBuildingElement (const GlobalId_type& GlobalId,
                                   const OwnerHistory_type& OwnerHistory)
          : ::ifcXML::IFC2x3::FINAL::IfcElement (GlobalId,
                                                 OwnerHistory)
          {
          }
    classe wrapper:
    codice:
     template < class T >
        class Wrapper : public T
        {
        public:        
        
    		Wrapper (): T(){};
    
    		Wrapper (const ::xercesc::DOMElement& e,
                      ::xml_schema::flags f = 0,
                      ::xml_schema::container* c = 0): T (e, f, c){};
    
    		Wrapper (const T& x,
                      ::xml_schema::flags f = 0,
                      ::xml_schema::container* c = 0): T (x, f, c){};
            void print(){
            
            };
        };
    non esiste per nulla nella mia classe template Wrapper e neanche posso implementare tutti i costruttori piu disparati(ho 2000 classi).
    c'è un modo per risolvere senza cavare tutti i costruttori specifici dalle classi che sono usate per il wrapper?

    ps.adesso ho la possibilità di inserire i costruttori di default in tutte le calssi, puo servire?
    grazie.

  5. #5
    Utente di HTML.it
    Registrato dal
    Jun 2003
    Messaggi
    4,826
    sono riuscito ad isolare e riprodurre l'errore in un semplice test:

    codice:
    #include "stdafx.h"
    
     template < class T >
        class Wrapper : public T
        {
        public:        
    		Wrapper (){};   
    	
        };
    
    class C {
    public:
    	C::C(){};
    	C::C(char *c,char* d, char* e){};
    };
    
    class B : public C{
    public:
    	B::B(){};
    	B::B(char *c,char* d, char* e) : C(c,d,e){};
    };
    
    
    int _tmain(int argc, _TCHAR* argv[])
    {
    	Wrapper<C>* pa = new Wrapper<C>("1","2","3");//errore errrore
    	return 0;
    }
    non so come risolvere.
    grazie.

  6. #6
    Utente di HTML.it
    Registrato dal
    Jun 2003
    Messaggi
    4,826
    ciao.
    per risolvere ho usato il meccanismo di forwarding.
    codice:
    template<typename B>
    class Wrapper : public B{
    
      template<typename T1>
      Wrapper (const T1& x1)
        : B (x1)
      {
      }
    
      template<typename T1, typename T2>
      Wrapper (const T1& x1, const T2& x2)
        : B (x1, x2)
      {
      }
    
      template<typename T1, typename T2, typename T3>
      Wrapper (const T1& x1, const T2& x2, const T3& x3)
        : B (x1, x2, x3)
      {
      }
    };
    cosi da quello che ho capito i costruttori possono essere i piu disparati(e con tipi diversi) ma vengono rindirizzati ai template col numero di parametro corretto invece che dare errore.
    se qualcuno ha tempo che puo spiegare meglio...ho anche letto su google che nel c++ 11 esiste un meccanismo detto di perfect forwarding in cosa differisce, che non ho capito bene?


    grazie.

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