У меня есть определение типа
typedef unsigned int my_type;
используемый в файле. Я хотел бы сделать это видимым через все мои файлы, не помещая его в заголовочный файл, включенный всем. Я не хочу идти путем заголовочного файла потому что как есть это будет единственным объявлением в заголовочном файле (и кажется ненужным добавить файл только для этого).
Существует ли способ сделать это?
Если вместо этого я имел:
typedef X my_type;
где X был класс, я должен буду включать X.h везде и иметь определение типа в конце X.h?
Я не хочу идти по маршруту файла заголовка, потому что в его нынешнем виде это будет единственное объявление в файле заголовка (и кажется ненужным добавлять файл только для этого).
В чем проблема? Кажется столь же ненужным избегать создания файла любой ценой.
Есть ли способ сделать это?
Насколько мне известно, нет.
нужно ли мне включать X.h везде и иметь typedef в конце X.h?
Нет, но это, наверное, лучший вариант. Единственная причина, по которой вы должны это делать, - это если X является шаблоном, и вам все равно нужны шаблоны в заголовках.
Нет, нет никакого способа обойтись без необходимости иметь typedef в файле заголовка, который включен везде, где он вам нужен, но нет, вы этого не сделаете обязательно нужно также включить файл Xh
во втором случае.
Если у вас есть
typedef X my_type;
И X
- это класс, вы можете сделать это (в заголовке, отличном от Xh
):
class X;
typedef X my_type;
Который вперед-объявляет X, и затем создает для него псевдоним типа. Затем пусть X.h
включает этот файл.
Затем, если вам нужно только неполное имя типа my_type
, вы можете включить очень короткий файл заголовка typedef, и вам нужно будет включить только Xh
, когда вам понадобится полный в любом случае определение для класса X
.
Объявление чего-либо (например, класса, typedef, функции) в единице перевода (например, файл cpp) на самом деле является стандартным способом сказать «это используется только в этом файле», потому что на него невозможно сослаться из других файлов . Единицы перевода не имеют представления о существовании друг друга, кроме деклараций (например, прототипов), общих для файлов .h, которые ничего не говорят о реализации. Это компоновщик, который берет все реализации и вставляет их вместе в двоичный файл.
Если вы хотите, чтобы он был виден за пределами файла - поместите его в файл .h и включите его. Как предлагали другие ответы, может быть полезен общий или глобальный файл .h. Некоторые компиляторы, которые используют предварительно скомпилированные заголовки, упрощают эту задачу - помещают их в предварительно скомпилированный заголовок.
Насколько я понимаю, этого не избежать. Почему бы вам не создать файл заголовка globals.h, содержащий только те объявления, которые вы хотите везде, и не включить их?
Не поддавайтесь соблазну зарыть где-нибудь свой typedef и надеяться, что «поскольку все остальное висит на заголовке», что он будет так же хорошо, как добавить глобальный заголовок - это крайне плохая практика иметь заголовки, которые не являются самодостаточными.
Также, чтобы не загромождать глобальное пространство имен, создайте свое собственное:
namespace MyTypes
{
typedef A B;
const unsigned int g_nMyGlobalType = 10;
// etc.
}
Таким образом, вы можете использовать свои глобальные переменные в удобном и незагроможденном виде:
MyTypes::B myVar; // etc
Я бы использовал маршрут заголовочного файла, это не так уж и плохо.
Нет, вам не нужно включать X.h везде, только там, где вы используете typedef.