Domanda

Ho una classe di classe matrice modello definita in un'intestazione chiamata " Matrix.h " ;.

Alcune matrici vengono utilizzate ripetutamente nel mio programma. Ho pensato di definirli in "Matrix.h" file di intestazione, in questo modo:

const Matrix<GLfloat> B_SPLINE_TO_BEZIER_MATRIX(4, 4, values);

Quando lo faccio, g ++ si lamenta di aver ridefinito la costante in questione. Ciò accade perché includo Matrix.h in due diversi file di origine. Quando vengono compilati i file oggetto per questi, entrambi finiscono con una definizione della matrice sopra, causando il messaggio di errore.

La mia domanda è: come posso evitare questa situazione? Voglio una costante accessibile a più di un file, ma non so dove metterlo.

È stato utile?

Soluzione

Se non si desidera dividerlo tra un'intestazione e un file di implementazione,

  1. Dichiara il tuo costante statico (o dichiaralo nello spazio dei nomi anonimo) per rendere privata la definizione. Linker non si lamenterà, ma comporterà più copie private tra le unità di compilazione.

    static Matrix<GLfloat> B_SPLINE_TO_BEZIER_MATRIX(4, 4, values);
    
  2. Crea una funzione inline che restituisce la costante. Le definizioni delle funzioni incorporate producono "debole" simboli nel file oggetto, quindi il linker eliminerà i duplicati e ne sceglierà uno.

    inline const Matrix<GLfloat>&
    GET_B_SPLINE_TO_BEZIER_MATRIX() {
        const static Matrix<GLfloat> B_SPLINE_TO_BEZIER_MATRIX(4, 4, values);
        return B_SPLINE_TO_BEZIER_MATRIX;
    }
    

Altri suggerimenti

Lo eviti:

  • Dichiarandolo extern nell'intestazione. Un simbolo può essere dichiarato un numero qualsiasi di volte.
  • Definendolo nell'implementazione, una sola volta.

scrivi semplicemente il tuo file header in questo modo

#ifndef HEADER_FILE_NAME_H

#define HEADER_FILE_NAME_H

// il codice del file di intestazione

#endif

questo farà in modo che non venga dichiarato più volte

Avvolgere i file di intestazione (.h) nei condizionali del preprocessore per impedire che vengano inclusi due volte nella tabella dei simboli del compilatore:

#ifndef HEADER_NAME
#define HEADER_NAME
// code...
#endif//HEADER_NAME

HEADER_NAME può davvero essere qualsiasi cosa, ma è meglio assicurarsi che sia qualcosa correlato al file per evitare ulteriori collisioni, in quanto si tratta solo di definire una macro di preprocessore vuota (che finisce anche nella tabella dei simboli).

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top