Должен ли я использовать статический в этом случае - PullRequest
2 голосов
/ 26 апреля 2011

У меня есть глобальное уникальное значение, которое я хочу использовать в exe-файле и разных DLL.

Для любого проекта, который желает его использовать, они могут просто включать defs.h

Мне было интересно, должен ли я объявить это как

// defs.h
const UINT UNIQUE_MESSAGE = 
    RegisterWindowMessage(_T("UNIQUE_MESSAGE-{E5476FDB-3E7E-4113-8132-1D87709BC46C}"));

ИЛИ

// defs.h
const static UINT UNIQUE_MESSAGE = 
    RegisterWindowMessage(_T("UNIQUE_MESSAGE-{E5476FDB-3E7E-4113-8132-1D87709BC46C}"));

В настоящее время я не нахожу ничего отличного от точки зрения потребителя кода,Есть ли какая-то проблема?Должен ли я использовать static или нет?

Ответы [ 3 ]

8 голосов
/ 26 апреля 2011

В C ++ уровень пространства имен const неявно static (, т. Е. Имеет внутреннюю связь ), если вы не пишете extern const.Таким образом, оба ваших синтаксиса в основном одинаковы.

§7.1.1 / 6 говорит, что

Объекты, объявленные как const и не объявленные явно extern, имеют внутреннюю связь.

Поэтому я хотел бы предложить следующее: (с минимальным учетом, например, исключая статический порядок инициализации fiasco и многие другие проблемы с static и глобальными переменными)

//in defs.h:
extern const UINT UNIQUE_MESSAGE;

//defs.cpp
const UINT UNIQUE_MESSAGE =  RegisterWindowMessage(_T("whatever"));
1 голос
/ 26 апреля 2011

Каждый CPP-файл, содержащий defs.h, будет иметь свой собственный экземпляр const в памяти. Если вы хотите иметь только один экземпляр в памяти, вы должны объявить его один раз в файле cpp, как вы это сделали:

const UINT UNIQUE_MESSAGE = RegisterWindowMessage(_T("UNIQUE_MESSAGE-{E5476FDB-3E7E-4113-8132-1D87709BC46C}"));

В def.h вы должны ссылаться на const как на внешний:

extern const UINT UNIQUE_MESSAGE;

0 голосов
/ 26 апреля 2011

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

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

<br /> defs.h:<br />const UINT getUniqueMessage(); <br /><br /> defs.c:<br /> const UINT getUniqueMessage()<br /> {<br /> static UINT UNIQUE_MESSAGE = RegisterWindowMessage(_T("UNIQUE_MESSAGE-{E5476FDB-3E7E-4113-8132-1D87709BC46C}")); // initialized once first time called<br /> return UNIQUE_MESSAGE;<br /> }

Теперь getUniqueMessage () можно вызывать где угодно, в том числе и во время инициализации других глобальных переменных, не опасаясь использования чего-то, что еще не может быть инициализировано.

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