Глобальные переменные и область видимости - C ++ - PullRequest
4 голосов
/ 13 февраля 2009

У меня небольшая проблема с созданием глобальной переменной. Я использую Visual Studio 2008 и стандарт C ++.

У меня есть два проекта, один - статическая библиотека, а второй - тестовая программа, использующая эту библиотеку. У меня есть глобальная переменная в global.h, как

#ifndef GLOBAL_H
#define GLOBAL_H

#include <string>

extern std::string globalWord;

#endif // GLOBAL_H!

У меня есть global.cpp, где я инициализирую эту переменную. Эта переменная используется внутри моего библиотечного проекта. Я устанавливаю значение для этой переменной из тестового проекта, но это значение не отражается в проекте библиотеки.

Я отладил, и он показывает новое значение в тестовом проекте, но когда элемент управления достигает проекта библиотеки, это значение переменной отображается пустым. Так ограничена ли область действия этой глобальной переменной только проектом, к которому она относится?

Или есть лучший способ сделать это? Я не хочу изменять параметры моей функции или конструктора в моей библиотеке, чтобы передать это значение.

Любая помощь будет отличной.

Edit:

Вот как эта переменная объявляется в global.cpp

#include <string>
#include "../global.h"

std::string globalWord = "";

Вот так я и использовал в своей библиотеке

#include "../global.h"
string text = globalWord;

Спасибо

Ответы [ 4 ]

7 голосов
/ 13 февраля 2009

Не используйте глобальные переменные. Просто не надо. Гораздо лучше, если вы ДОЛЖНЫ иметь глобально доступные данные, это использовать глобальную функцию, которая будет возвращать globalWord, например:

std::string globalWord()
{
    static std::string word("Hi Mom");
    return word;
}

Это избавит вас от проблем с порядком инициализации (см. Пункт 4 «Эффективное C ++»).

5 голосов
/ 13 февраля 2009

С ключевым словом "extern" вы сообщаете компилятору, что фактическая переменная существует где-то еще. Вы также должны создать переменную с тем же именем без внешнего, в одном и только одном месте. Обычно вы получите ошибку от компоновщика, если вы определите два из них, но если кто-то находится в библиотеке, а другой нет, он может не понять это.

Редактировать: убедитесь, что global.cpp есть только в библиотеке или тестовой программе, а не в обеих.

3 голосов
/ 13 февраля 2009

Вероятно, проблема связана с порядком инициализации. Когда программа связана, есть 2 места, где globalWord используется при инициализации:

  1. при инициализации text ("string text = globalWord; ")
  2. сама инициализация globalWord

К сожалению, стандарт C ++ не определяет порядок инициализации глобальных переменных, поступающих из разных модулей. Нечто похожее на ответ Мэтта об использовании функции или простого класса (например, синглтона) для доступа к глобальному значению является обычным способом обеспечения соблюдения определенного порядка инициализации.

Часто задаваемые вопросы по C ++ говорят об этом немного - если вы планируете изменить globalWord в своей программе, ситуация становится немного более сложной, чем они обсуждают, потому что они, кажется, не относятся к настройке адреса значение, скрытое за функцией «конструировать при первом использовании». Обычно для чего-то подобного требуется что-то вроде одноэлементного класса .

2 голосов
/ 13 февраля 2009

Тип поведения, который вы описываете, больше похож на проблему, когда у вас есть DLL, но вы говорите, что ваша библиотека статична, что выглядит странно.

В любом случае, позаботьтесь о глобальных переменных в нескольких библиотеках, если у вас есть библиотека общего кода (DLL), вы получите значение для каждой части. Проверьте этот вопрос, может быть полезным.

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