Ошибка компоновщика дублированного символа c ++ при совместном использовании переменной в пространстве имен - PullRequest
3 голосов
/ 15 сентября 2011

Все еще относительно новый для C ++

У меня есть переменная заголовка с пространством имен с несколькими константами, которая выглядит примерно так

namespace blah {
    const std::string x="foo";
}

У меня нет проблем с доступом к переменным таким способом - dosomething (blah :: x); и т.д. Теперь я хочу изменить переменную, чтобы она могла быть изменена. Если я просто вынимаю const, я получаю ошибку компоновщика "duplicate symbol blah :: x". Добавление экстерна здесь не помогает:

namespace blah {
    extern std::string x;
} 

Это говорит о том, что extern включен по умолчанию, и я получаю ту же ошибку повторяющегося символа. Какой правильный способ сделать это?

(РЕДАКТИРОВАТЬ в последнем случае, я пока не хочу устанавливать значение переменной. Я хочу получить его в другом месте и поделиться значением. Чтобы уточнить - я хочу избавиться от const, чтобы я мог изменить значение (Например, используя аргументы командной строки. Когда я избавляюсь от const, я получаю ошибки о повторяющихся символах.)

Ответы [ 3 ]

7 голосов
/ 15 сентября 2011

В заголовочном файле вы должны объявить переменную:

//blah.h
namespace blah {
   extern std::string x; //declaration
}

И в исходном файле вы должны определить как:

//blah.cpp
#include "blah.h"
namespace blah {
    std::string x="foo"; //definition
}

Теперь включите blah.h в любое количество файлов. Вы не увидите ошибки переопределения.

Если вы хотите избавиться от const (как вы сказали в комментарии), просто удалите его, как я.

2 голосов
/ 15 сентября 2011

Объявите extern в заголовочном файле:

code.h

namespace blah {
  extern std::string x;
};

... и определите в одном файле CPP ...

code.cpp

std::string blah::x = "foo";
0 голосов
/ 15 сентября 2011

Создайте заголовочный файл, который объявляет ваш extern:

namespace blah {
    extern std::string x;
} 

Затем создайте исходный файл, содержащий определение:

namespace blah {
    std::string x="foo";
} 

Таким образом, определение компилируется один раз в lib (с которым вы будете ссылаться), и не будет определено несколько раз (везде, где вы включаете заголовок).

...