Могу ли я вернуть ссылку на экземпляр статического класса (singleton) в этом классе в C ++? - PullRequest
2 голосов
/ 11 января 2012

Обычно, когда я реализую синглтон, я делаю экземпляр динамическим и имею функцию-член для его удаления. В этом случае я работаю на встроенном устройстве, и мне сказали, что я не могу использовать динамическую память. Допустимо ли для класса иметь статический экземпляр внутри объявления класса и возвращать его по ссылке?

(Безопасность потоков здесь не имеет значения.)

class Foo {
private:
    static Foo singleton;

    Foo() { }
    Foo(const Foo &rhs);
    Foo &operator=(const Foo &rhs);

public:
    inline static Foo &Instance(void) {
        return singleton;
    }
};

Foo Foo::singleton;

Ответы [ 3 ]

12 голосов
/ 11 января 2012

Возможно иметь статический экземпляр, но нежелательно иметь его на уровне класса, потому что может случиться так, что он еще не инициализирован при доступе (из-за не полностью определенного порядка статической инициализации).Вместо этого вы должны использовать локальную статическую функцию:

class Foo {
private:
    Foo() { }
    Foo(const Foo &rhs);
    Foo &operator=(const Foo &rhs);

public:
    inline static Foo &Instance(void) {
        static Foo singleton;
        return singleton;
    }
};

Таким образом, гарантируется, что он будет инициализирован при первом вызове функции Instance.

2 голосов
/ 11 января 2012

Да ничто не запрещает вам делать это. Вы пытались сначала скомпилировать ?

Кроме того, встроенная функция не требуется для функции-члена, определенной в объявлении класса. Еще одно примечание: убедитесь, что вы понимаете последствия использования Singleton (это редко хорошая идея, но в некоторых конкретных случаях может быть полезным - это предмет спора, но в конечном итоге прагматизм всегда побеждает). Также читайте это, ответы и комментарии. Опыт поможет лучше рассмотреть варианты использования. Просто, пожалуйста, никогда не допускайте неявного создания / уничтожения, если вы реализуете шаблон синглтона.

Говоря об этом, есть библиотека Singularity, предложенная для повышения (http://boost.org ваше стандартное дополнение к библиотеке), которая предоставляет функции отдельно: 1. Принудительно использовать только один экземпляр 2. При желании сделать его доступным глобально. Это доступно там: https://github.com/icaretaker/Singularity (документ в источниках ...)

1 голос
/ 11 января 2012

Да, вы можете сделать это.

Обратите внимание, что нет никаких гарантий порядка создания и уничтожения статических объектов в единицах компиляции. Следовательно, лучше всего объявлять static в статической функции-члене доступа.

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

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