Это мой первый вопрос о переполнении стека, поэтому будьте нежны.Достижение поведения C# «readonly» в C++
Позвольте мне сначала объяснить точное поведение, которое я хотел бы видеть. Если вы знакомы с C#, то знаете, что объявление переменной как «readonly» позволяет программисту назначить некоторое значение этой переменной ровно один раз. Дальнейшие попытки изменить переменную приведут к ошибке.
Что мне нужно: я хочу, чтобы все и все однотонные классы, которые я определяю, могут быть спроектированы точно как раз в моей программе (подробности внизу).
Мой подход к реализации своей цели является использование EXTERN объявить глобальную ссылку на одной тонны (который я позже создать экземпляр в то время, я выбираю. То, что я вроде выглядит так,
namespace Global
{
extern Singleton& mainInstance; // not defined yet, but it will be later!
}
int main()
{
// now that the program has started, go ahead and create the singleton object
Singleton& Global::mainInstance = Singleton::GetInstance(); // invalid use of qualified name
Global::mainInstance = Singleton::GetInstance(); // doesn't work either :(
}
class Singleton
{
/* Some details ommited */
public:
Singleton& GetInstance()
{
static Singleton instance; // exists once for the whole program
return instance;
}
}
Однако это действительно не работает, и я не знаю, куда идти отсюда
Некоторые подробности о том, что я против:.
Я беспокоюсь о многопоточности, как я работаю на код, который будет обрабатывать логику игры, а , общаюсь с несколькими сторонними процессами и другими процессами, которые я создам. В конце концов у меня было бы для реализации какой-то синхронизации, поэтому несколько потоков могли бы получить доступ к информации в классе Singleton, не опасаясь. Поскольку я не знаю, какие оптимизации я мог бы сделать , или точно, что потоки влекут за собой (никогда не выполнял реальный проект, используя его), я думал, что возможность предсказуемого контроля при создании экземпляров Singletons будет хорошим Вещь.
Представьте, что процесс A создает процесс B, где B содержит несколько синглтонов, распределенных по нескольким файлам и/или библиотекам. Это может быть настоящий кошмар, если я не могу надежно обеспечить порядок создания этих одноэлементных объектов (потому что они могут зависеть друг от друга, а вызов методов на объекте NULL обычно является плохим веществом).
Если бы я был на C#, я бы просто использовал ключевое слово readonly, но есть ли способ реализовать это поведение (поддерживается компилятором) на C++? Это даже хорошая идея? Спасибо за любую обратную связь.
Редактировать
Если бы я был заперт в следованию примере кода выше, выбранный ответ будет самый простой способ сделать то, что мне было нужно. Я решил изменить шаблон от синглтона, хотя, хотя я только планирую когда-либо создавать один из этих объектов EntryPoint.
class EntryPoint
{
/* Intentionally defined this way to discourage creation */
EntryPoint(const EntryPoint &); // undefined & private
EntryPoint& operator=(const EntryPoint &); // undefined & private
// public
EntryPoint()
{
/* All of the action is performed here! */
}
/* Other supporting functions */
}
// The easier to understand main function!
int main()
{
EntryPoint * ep = new EntryPoint(); // transfer control to the entrypoint
delete ep;
}
Одна из причин, почему я думал, я должен был бы все эти одиночек, я планирую создать большую архитектуру, которая будет поддерживать модульные приложения плагин типа. Я также нуждался в большей проверке ошибок и защите памяти, чтобы минимизировать утечки памяти. Я был рад узнать, что кросс-платформенный Qt (http://qt.nokia.com/) предлагает охраняемый указатель и другие интересные функции.
Звучит так: 'const' должен делать трюк. Но нет, я не думаю, что это хорошая идея. Синглтоны достаточно плохи в их «нормальном» воплощении. Сделать их еще более сложными - это только возвращение и укусить вас. Почему у вас все эти синглы? Самый простой способ контролировать порядок создания экземпляров - это прекратить делать половину ваших переменных static/globals/singletons – jalf