2010-06-05 2 views
1

Это мой первый вопрос о переполнении стека, поэтому будьте нежны.Достижение поведения 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/) предлагает охраняемый указатель и другие интересные функции.

+3

Звучит так: 'const' должен делать трюк. Но нет, я не думаю, что это хорошая идея. Синглтоны достаточно плохи в их «нормальном» воплощении. Сделать их еще более сложными - это только возвращение и укусить вас. Почему у вас все эти синглы? Самый простой способ контролировать порядок создания экземпляров - это прекратить делать половину ваших переменных static/globals/singletons – jalf

ответ

1

Почему бы просто не использовать Singleton::GetInstance? Зачем вам хранить его в глобальном (readonly)? Это также решает проблемы зависимостей.

+0

+1 Вот как я бы назвал метод Singleton GetInstance. –

+0

Половина меня хочет знать, если это возможно. Но то, что я пытаюсь сделать, - это отдельный экземпляр доступа. Я чувствую, что когда-нибудь я смогу создать класс AccessManager, который будет отвечать за ускорение доступа к глобальным данным (что может потребовать запроса базы данных, кто знает) с использованием методов кеширования или чего-то более сложного. В настоящее время это не так плохо, потому что это просто, но я не хочу быть в ситуации, когда его трудно оптимизировать, потому что у меня много вызовов Singleton :: GetInstance() на всей кодовой базе. –

+0

Можете ли вы создать класс (или несколько классов) со статическими методами, такими как 'GetGraphicsEngine' и' GetInputEngine', которые на данный момент называют 'Singleton :: GetInstance'? – strager

1

позволяют только доступ по телефону:

Singleton::GetInstance 

Принудительно это путем внесения копирования и назначению конструкторов частных

private: 
    Singleton(){} 
    Singleton(Singleton const&){}; //copy ctor private 
    Singleton& operator=(Singleton const&){}; 
+0

и Singleton :: GetInstance статично – Joshua

0

Представьте себе, если процесс А создает процесс В, где B содержит несколько Singletons

Что именно вы думаете, что вам нужны все эти Синглтоны для? Вы знаете о Anti Singleton Movement? ;-)

+0

Забавное видео :) –

+0

@Matt: «Забавно», вы имеете в виду «интересный» или «смешной»? – fredoverflow

+0

Немного обоим, я думаю :) Я только просматривал первые 10 минут, и хотя я согласен с тем, что глобального государства следует избегать (разве мы не знаем все это?), Я также по опыту знаю, что он существует: он называется внешний мир (базы данных, другие приложения, ...). Тем не менее я рад за ссылку. И поздравление с достижением 4k :) –

Смежные вопросы