2017-02-07 29 views
-1

Я пытаюсь использовать константу int SIZE, которая объявлена ​​в пространстве имен TaxConstants.hpp TAXCONSTANTS в других местах моего проекта. Когда я пытаюсь скомпилировать, я получаю «неопределенная ссылка на 'SIZE' везде ссылается что SIZEC++ Ссылка на extern const в пространстве имен

файловой TaxConstants.hpp

#ifndef TaxConstants_hpp 
#define TaxConstants_hpp 


namespace TAXCONSTANTS 
{ 
    extern const int SIZE = 4; // I have tried with and without extern 
} 

#endif //TAXCONSTANTS_HPP 

main.cpp

#include <iostream> 
#include "TaxConstants.hpp" 
using namespace std; 
using namespace TAXCONSTANTS; 

int main() 
{ 
extern const int SIZE; 

// This is a struct defined in another file. It is a sample of my use for SIZE. I left out the #include above to simplify things. 
taxPayer payers[SIZE]; 

//More code 

return 0; 
} 

Дополнительная информация:. Это является школьным проектом, и мой урок сделал обязательным объявление констант в файле TaxConstants.hpp в пространстве имен TAXCONSTANTS.

Всего 5 файлов, файл с моим fu nctions имеет ту же неопределенную ссылку на ошибку SIZE.

Я потратил часы на поиск похожих объяснений на функцию extern и пространства имен, но большинство предложений против этого в первую очередь предлагают другое решение. Я, к сожалению, не могу их использовать. Другие ошибки, которые люди испытывали, получали «несколько украшений», которых у меня нет.

EDIT

См Brians объяснение ниже для более подробно.

Что мне нужно сделать, это определить

const int SIZE = 4; 

в файле TaxConstants.hpp в пространстве имен TAXCONSTANTS.

Затем удалить 'extern const int SIZE;' из моего основного файла и вместо этого ссылка SIZE by TAXCONSTANTS :: РАЗМЕР везде, где я хотел использовать размер.

Это основное пространство имен, о котором я совсем забыл.

+0

Возможный дубликат: [Почему «extern const int n» не работает должным образом?] (Http://stackoverflow.com/questions/14894698/why-does-extern-const-int-n-not-work -а-ожидаемый) –

+0

Я не считаю, что это имеет какое-то отношение к пространствам имен, но проблема 'extern const'. –

+0

Вы можете видеть другие сообщения, используя поисковые термины [stackoverflow C++ extern const] (https://www.google.com/search?q=stackoverflow+c%2B%2B+extern+const&ie=utf-8&oe=utf-8) –

ответ

0

Если вы определяете SIZEбез ключевое слово extern, оно будет иметь внутреннюю связь, так как оно равно const. Вы можете ссылаться на него в main.cpp как TAXCONSTANTS::SIZE. Это рекомендуется, так как компилятор сможет встроить значение везде, где используется SIZE.

Если определить SIZEсextern ключевого слова, оно будет иметь внешнюю связь, и это не должно быть в заголовке, если вы не хотите использовать несколько ошибок определения. Вы должны определить его в файле .cpp, который будет связан с остальной частью программы. В этом случае во всей программе будет только одна копия SIZE. Вам следует избегать такого подхода (предпочитая вместо этого подход без extern) , если только по какой-то причине вам действительно нужна только одна копия SIZE во всей программе.

В обоих случаях SIZE будет членом пространства имен TAXCONSTANTS.

Ваши попытки пополнить свой счет SIZE внутри main не работает так, как вы думаете! Следующий внутри main:

extern const int SIZE; 

фактически имеет эффект объявляя SIZE в глобальном пространстве имен. Поскольку в глобальном пространстве имен нет определения SIZE, вы получаете неопределенные ссылочные ошибки во время соединения. Это не правильный способ ссылаться на переменную SIZE, определенную в TAXCONSTANTS.

+0

Спасибо, я понял это прямо перед тем, как проверить здесь. Вы писали, я ошибался и должен был использовать TAXCONSTANTS :: SIZE. – Bow

0

Несколько проблем со всем подходом.

  1. Ваш

    extern const int SIZE; 
    

    в main является декларацией const int объекта SIZE из глобального пространства имен - ::SIZE. Это SIZE не имеет абсолютно никакого отношения к вашему TAXCONSTANTS::SIZE. Такой глобальный объект ::SIZE не определен в вашей программе, поэтому вы получаете ошибку «undefined reference».

    С тех пор, как вы уже объявили TAXCONSTANTS::SIZE в файле заголовка, вам не нужно повторно обновлять SIZE в main. Зачем ты это делаешь?

    Просто удалить объявление из main и использовать SIZE из TAXCONSTANTS либо через using namespace TAXCONSTANTS или указав полное имя TAXCONSTANTS::SIZE.

  2. Объявление, которое у вас есть в файле заголовка, фактически представляет собой определение .Включение этого файла заголовка в несколько единиц перевода приведет к другой ошибке: несколько определений одного и того же объекта с внешней связью.

    Если вы хотите объявить глобальный постоянный объект, вы должны держать лишь не-определяющую декларацию в заголовочном файле

    namespace TAXCONSTANTS 
    { 
        extern const int SIZE; // declaration, not definition 
    } 
    

    и вынести определение в одном из файлов реализация

    namespace TAXCONSTANTS 
    { 
        extern const int SIZE = 4; // definition 
    } 
    
  3. Однако представляется, что вы планируете использовать эту константу как интегральное выражение константы (как размер массива в объявлении массива). Константа extern const int, объявленная без инициализатора, не будет работать для этой цели.

    Просто забыть о extern и объявить нормальную постоянную с внутренним связыванием в заголовочном файле

    namespace TAXCONSTANTS 
    { 
        const int SIZE = 4; // definition with internal linkage 
    } 
    

    , а затем просто использовать в везде, где он необходим

    using namespace TAXCONSTANTS; 
    
    int main() 
    { 
        taxPayer payers[SIZE]; 
        ... 
    } 
    

    или

    // no 'using namespace TAXCONSTANTS;' 
    
    int main() 
    { 
        taxPayer payers[TAXCONSTANTS::SIZE]; 
        ... 
    } 
    
+0

Спасибо, я должен был написать его, как TAXCONSTANTS :: SIZE, как вы упомянули. – Bow