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

    [c++]template e metodi scrittura codice

    ciao.
    Volevo chiarirmi come creare delle classi template in un progetto gia esistente.
    ho visto che il modo piu' semplice è quello di inserire tutto in un header .h , ho visto anche includere in un h un file .inp con le definizioni , ma non ho capito bene.
    Mi piacerebbe una scritture con h e cpp.
    Infine non capisco perchè le funzioni vadano inline, è solo un problema di efficenza o c'è qualcosa di piu?
    grazie.

  2. #2
    Risposta breve: i template vanno negli header, dato che si tratta di generatori di funzioni, e quindi le loro definizioni devono essere completamente accessibili al momento della loro istanziazione. Alcuni tengono le dichiarazioni e le definizioni separate per chiarezza, ma comunque alla fin della fiera devono essere incluse con dei #include in ogni file che li utilizza.

    Teoricamente è possibile non includere la definizione, ma metterla in un file .cpp separato, ma lì bisogna istanziare (con una sintassi che non ricordo) tutti i template richiesti altrove - ovvero, far effettivamente generare al compilatore le istanze di template richieste negli altri .cpp.
    In caso contrario, ci si ritrova con errori di linking (undefined reference to function...), esattamente come quando si dichiara e usa una funzione e non la si definisce (ricorda: l'equivalente della definizione di una funzione normale è l'istanziazione del template per lo specifico tipo, dato che il template in sè è un generatore di funzioni, e ciascuna funzione da esso generata è una funzione separata).

    Lo standard C++ (non ricordo se la versione del 1998 o del 2003) aveva previsto un modo per separare implementazione e dichiarazione dei template in maniera analoga al classico ".h/.cpp" delle funzioni "normali" (mi pare che la parola chiave fosse export), ma nessuno l'ha implementato (tranne forse Comeau) perché era difficile aggiungerla ai compilatori C++ attuali, e il nuovo standard C++ (approvato da qualche giorno! ) l'ha definitivamente cassato come "deprecato".

    Quanto ad inline, serve in alcuni casi per "aggirare" la ODR (One Definition Rule).
    Il C++ richiede che ogni funzione/oggetto/... sia definito una sola volta tra tutte le "translation units" (ovvero, tra tutti i .cpp). Questo perché se più funzioni/... non-static (con external linkage, ovvero disponibili per gli altri .cpp se viene fornito il prototipo) che hanno lo stesso nome sono definite nei vari .cpp, il linker alla fine non può sapere qual è la definizione "giusta" al momento di collegare i moduli oggetto.

    Le funzioni inline fanno eccezione: in effetti normalmente le funzioni inline vengono messe negli header, e quindi vengono definite in ciascun .cpp che le usa. Questo perché, se il compilatore le deve espandere in linea (cosa che peraltro può scegliere di non fare), deve avere il loro sorgente disponibile al momento della compilazione di ciascun .cpp. D'altra parte, se oltre ad inline non si specifica anche static, ogni .cpp esporterà (con extern linkage) le funzioni inline che sono definite in esso (in effetto è lecito che un .cpp si riferisca ad una funzione inline definita in un altro .cpp facendo fare il lavoro di collegamento al linker, anche se molto probabilmente in tal caso non sarà espansa in linea).
    Per questo motivo l'ODR ha un'eccezione per le funzioni inline: se una funzione è marcata come inline, è consentito che sia definita con linkage extern in più .cpp, e il linker, al momento di linkare insieme i moduli oggetto, ne sceglierà una qualunque a sua discrezione. Ovviamente perché tutto questo funzioni correttamente le definizioni di ciascuna funzione inline devono essere le stesse in ogni .cpp (lo standard dice che se le definizioni duplicate delle funzioni inline differiscono tra di loro si va incontro a "undefined behavior").

    Per i template vale la stessa eccezione alla ODR - ma solo se si tratta di "veri" template: le specializzazioni esplicite di fatto non dipendono più da un parametro template, per cui "ridiventano funzioni normali", e pertanto, se vengono definite in più .cpp (via inclusione di header), causano un errore di linker (multiple definition of function...). In tal caso è opportuno mettere la keyword inline di fronte alla specializzazione parziale, in modo che il linker accetti le definizioni duplicate in delega alla ODR. In teoria si potrebbe semplicemente dichiarare la specializzazione parziale dopo il template, e definirla in un .cpp a parte, ma secondo me il gioco non vale la candela (sparpagliare qua e là pezzi di template diventa poco gestibile).

    Per ulteriori informazioni su queste ed altre bizzarrie dei template, dai un'occhiata qui.
    Amaro C++, il gusto pieno dell'undefined behavior.

  3. #3
    Originariamente inviato da MItaly
    Risposta breve: ..........
    meno male che era una risposta breve, se fosse stata una risposta lunga

  4. #4
    Originariamente inviato da DiegoFilippo
    meno male che era una risposta breve, se fosse stata una risposta lunga
    La risposta breve era solo il primo paragrafo, che è tutto quello che è necessario sapere normalmente. Il resto è approfondimento sulle altre sue domande.
    Amaro C++, il gusto pieno dell'undefined behavior.

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.