Visualizzazione dei risultati da 1 a 6 su 6
  1. #1

    [C++] headers

    Salve a tutti
    Potreste spiegarmi che differenza c'è nell'utilizzare queste due tipologie di header?
    tipologia 1:
    file header.h
    codice:
    #ifndef HEADER
    #define HEADER
    
    int AggiungiUno(int* a) {*a++;} 
    
    #endif
    tipologia 2:
    file header.h
    codice:
    int AggiungiUno(int*);
    file header.cpp
    codice:
    #include "header.h"
    AggiungiUno(int* a) {*a++;}

  2. #2
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Negli header file non va *mai* scritto codice di funzioni o metodi (a parte quelli inline di una classe). Dato che le direttive #include non fanno altro che includere fisicamente il file specificato all'interno del file sorgente, immagina cosa succederebbe se ad esempio in stdio.h fosse definito il codice di tutte le sue funzioni: anche per un semplice "hello world" che utilizza solo una banale printf(), dovresti ricompilare tutto il codice della libreria!
    Negli header file ci vanno solo le dichiarazioni di funzione, classi, tipi di dato ed eventuali direttive al preprocessore, mentre il codice va definito in appositi file sorgente con estensione c/cpp o quello che è (in pratica, il secondo esempio che hai postato).

    Ah, per inciso: per motivi di associatività di operatori, *a++ non incrementa di uno il valore puntato da 'a', ma incrementa il puntatore 'a' e poi lo dereferenzia (inutilmente), quindi non solo non dà il risultato desiderato ma può anche essere causa di violazione di accesso alla memoria. Sostituisci con (*a)++;
    every day above ground is a good one

  3. #3
    Pensavo che mettendo il codice dell'header tra:
    #ifndef HEADER
    #define HEADER

    e #endif venisse comunque eseguito una sola volta, indifferentemente da quante
    volte viene incluso..

  4. #4
    Utente di HTML.it
    Registrato dal
    Jul 2008
    Messaggi
    1,326
    Quelle sono #include guard e servono per evitare inclusioni multiple di header file (e conseguentemente ridefinizioni di strutture o classi). Resta comunque il concetto che negli header file non vanno implementati metodi o funzioni, ma solo dichiarati.
    every day above ground is a good one

  5. #5
    Originariamente inviato da VisRoboris
    Pensavo che mettendo il codice dell'header tra:
    #ifndef HEADER
    #define HEADER

    e #endif venisse comunque eseguito una sola volta, indifferentemente da quante
    volte viene incluso..
    Che c'entra? Gli header guards evitano che il contenuto del .h venga ripetuto più volte se il .h viene incluso più volte nello stesso .cpp (cosa che può capitare ad esempio se includi direttamente il .h e magari un altro .h che lo include a sua volta), ma se inserisci il corpo della stessa funzione in più file .cpp il linker, al momento di riunire i vari moduli oggetto in un unico eseguibile, si ritroverà con più definizioni della medesima funzione, e non saprà quindi quale scegliere. Il divieto di avere più di una definizione della medesima funzione è la cosiddetta One Definition Rule (ODR).

    Questa restrizione non si applica alle funzioni inline e template, che vengono marcate in modo particolare dal compilatore in modo che il linker, anche se ne trova più di una con stesso nome e signature, ne scelga una qualunque (suppone che siano tutte uguali).

    In ogni caso, il formato "normale" degli header è:
    codice:
    // header.h
    #ifndef HEADER_H_INCLUDED
    #define HEADER_H_INCLUDED
    
    int AggiungiUno(int* a);
    
    #endif
    codice:
    // header.cpp
    #include "header.h"
    
    int AggiungiUno(int* a)
    {
        (*a)++;
    }
    In questa maniera si evitano sia i problemi derivanti dall'inclusione multipla che le definizioni duplicate.

    Tra parentesi, sarebbe meglio, rispetto a HEADER, usare una cosa del tipo HEADER_H_INCLUDED, in modo da diminuire il rischio di collisioni con altri nomi o macro; alcuni usano iniziare i nomi degli include guard con degli underscore, ma è pessima pratica, dato che i nomi che iniziano per underscore seguito da maiscola sono riservati per il compilatore in ogni scope.
    Amaro C++, il gusto pieno dell'undefined behavior.

  6. #6
    Ho capito finalmente, grazie a tutti ;D

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.