2016-01-03 7 views
1

Я заголовочный файл, в котором я декларировать некоторые константы с ехЬегпом:C++ Как делить константы с экстерном между кастами - Ошибка: классом хранения указано

#ifndef CONSTANTS_H 
#define CONSTANTS_H 

#include <string> 

class Constants 
{ 
    public: 
     Constants(){} 
     extern const std::string DELIMITER; 
     extern const std::string FILENAME; 
     extern const int BLUCAR; 
     extern const int REDCAR; 
     extern const int EMPTY; 
     extern const int SPARSE_LIM; 
    protected: 
    private: 
}; 

#endif // CONSTANTS_H 

Тогда в источнике я определяю их следующим образом:

#include "constants.h" 

extern const std::string DELIMITER = ","; 
extern const std::string FILENAME = "cars.csv"; 
extern const int BLUCAR = 1; 
extern const int REDCAR = 2; 
extern const int EMPTY = 0; 
extern const int SPARSE_LIM = 5; 

Почему компилятор дает мне ошибку: класс хранения указан для «DELIMITER»?

+0

Удаление определения класса, конструктор и модификаторы доступа решается ошибка. Правильно ли это? – rh0x

ответ

4

Во-первых, они, похоже, не являются членами класса. То, как вы используете extern, похоже, вы предназначались для того, чтобы они были бесплатными. Возможно, в пространстве имен. Выведите их из этого класса.

Затем, определив их, оставьте extern.

В этом контексте это означает «найти эту переменную в другом месте». Вы не хотите его искать в другом месте. Это здесь!

// Header 
namespace Constants { 
    extern const std::string DELIMITER; 
    extern const std::string FILENAME; 
    extern const int   BLUCAR; 
    extern const int   REDCAR; 
    extern const int   EMPTY; 
    extern const int   SPARSE_LIM; 
} 


// Source 
namespace Constants { 
    const std::string DELIMITER = ","; 
    const std::string FILENAME = "cars.csv"; 
    const int   BLUCAR  = 1; 
    const int   REDCAR  = 2; 
    const int   EMPTY  = 0; 
    const int   SPARSE_LIM = 5; 
} 

Помните, что вы сделали бы то же самое для определения объектов static!

+0

Я понимаю, что вы говорите, но мне нужно определить их в исходном файле, чтобы я мог включить заголовочный файл, в котором они только объявлены. Таким образом, когда я изменяю значение, файлы, в которые включен константы.h, не нужно перекомпилировать. Я не знаю, правильно ли я говорю, но я понял, что здесь: http://stackoverflow.com/questions/9649405/c-best-practices-for-constants – rh0x

+0

@ rh0x: Да, определите их в исходном файле. Я показал вам, как это сделать. –

2

Я думаю, вы либо хотите использовать статические члены в своем классе, используйте пространство имен вместо класса, либо поместите свои константы в глобальное пространство имен.

Для статических членов:

class Constants 
{ 
    public: 
     Constants(){} 
     static const std::string DELIMITER; 
     static const std::string FILENAME; 
     static const int BLUCAR; 
     static const int REDCAR; 
     static const int EMPTY; 
     static const int SPARSE_LIM; 
    protected: 
    private: 
}; 

и в исходном файле

const std::string Constants::DELIMITER = ","; 
const std::string Constants::FILENAME = "cars.csv"; 
const int Constants::BLUCAR = 1; 
const int Constants::REDCAR = 2; 
const int Constants::EMPTY = 0; 
const int Constants::SPARSE_LIM = 5; 

Однако, это выглядит как ваш класс больше похож на пространство имен, чем класс, так как не было бы никакого смысла создание экземпляров.

Но есть и другой вариант. Вы можете даже не хотите использовать класс или пространство имен, а просто их всех в глобальном пространстве имен:

// header 
extern const std::string DELIMITER; 
extern const std::string FILENAME; 
extern const int BLUCAR; 
extern const int REDCAR; 
extern const int EMPTY; 
extern const int SPARSE_LIM; 

// source 
const std::string DELIMITER = ","; 
const std::string FILENAME = "cars.csv"; 
const int BLUCAR = 1; 
const int REDCAR = 2; 
const int EMPTY = 0; 
const int SPARSE_LIM = 5; 
+0

Да, вы правы! Также, как и «Легкость гонки на орбите», вероятно, лучшим вариантом является использование пространства имен. Спасибо! – rh0x

+1

@ rh0x: Обратите внимание, что вам нужно только пространство имен, если вы хотите сгруппировать их каким-либо образом, чтобы использовать префикс пространства имен для доступа. Если вы просто хотите использовать 'DELIMITER' вместо' Constants :: DELIMITER', то размещение его в глобальном пространстве имен может быть тем, что вы хотите. –