уже определено в .obj, хотя с #ifndef #define #endif - PullRequest
0 голосов
/ 09 июня 2018

Итак, у меня есть вложенное пространство имен в заголовочном файле.Внутри пространства имен у меня есть отдельные данные.Однако при компиляции я получаю «уже определено в <..>. Obj».Я попытался возиться со встроенным, но, видимо, встроенный работает только с функциями.Вот мой код:

#ifndef HEADER_H
#define HEADER_H

namespace sod {
    namespace e {
        const int _2D = 0;
        const int _3D = 1;
        const int _CUSTOM = 2;
        const char *text1 = "I AM A C STRING";       // <-- char const * const sod::e::text1 (?text1@e@sod@@3PBDB) already defined in main.obj
        const char *text2 = "I AM ALSO A C STRING";  // <-- char const * const sod::e::text2 (?text2@e@sod@@3PBDB) already defined in main.obj
    };
};

#endif

Я использую редактор Visual Studio 2017.

Любая помощь приветствуется.

Ответы [ 2 ]

0 голосов
/ 10 июня 2018

Кто-то отправил правильный ответ, который помог мне, но я думаю, что он удалил сообщение.

Простой ответ - использовать extern.

В моем заголовочном файле:

#ifndef HEADER_H
#define HEADER_H

namespace sod {
    namespace e {
        extern const int _2D;
        extern const int _3D;
        extern const int _CUSTOM;

        extern const char *text1;
        extern const char *text2;
    };
};

В файле cpp:

#include "header.h"

namespace sod {
    namespace e {
        const int _2D = 0;
        const int _3D = 1;
        const int _CUSTOM = 2;

        const char *text1 = "I AM A C STRING";
        const char *text2 = "I AM ALSO A C STRING";
    };
};
0 голосов
/ 09 июня 2018

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

Ваши строковые указатели имеют внешнюю связь, поскольку они не заявлено const.Из-за этого вы получите несколько ошибок определения, когда этот заголовочный файл включен в несколько блоков перевода.Вам не разрешено иметь несколько не встроенных определений объектов с внешними связями в вашей программе.

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

const char *const text = "whatever";

Обратите внимание, где в объявлении помещается дополнительный const.

Но если вы хотели, чтобы ваши указатели были модифицируемыми глобальными переменными, то этодругая история.В компиляторах C ++ 17 вы можете достичь этого, просто добавив inline

inline const char *text = "whatever";

В pre-C ++ 17 вам придется перепрыгивать через более сложную комбинацию обручей с объявлениями externв заголовочном файле.(Выполните поиск по темам о глобальных переменных - это хорошо освещено в SO.)

PS Включающие охранники не имеют ничего общего с предотвращением ошибок компоновщика.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...