LINUX.ORG.RU

Cpp и реализация Singleton

 ,


0

1

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

class SettingInterface {
public:
    static SettingInterface& getInstance(QString const& filename) {
        static SettingInterface instance;
        static QString config = filename;
        qDebug() << "Using: " << config;
        return instance;
    }

private:

    // Следующие 3 конструктора _не перегружать_ (singleton)
    SettingInterface();
    SettingInterface(SettingInterface const&);
    void operator=(SettingInterface const&);
};

Затем в другом классе, каждый раз при вызове SettingInterface(«config.ini») у меня будет выводиться именно config.ini (даже если в след. раз кто-то попробует вызвать его с другим именем).

Вопрос в том, что мне нужно как-то получить доступ к этому config. Попытался добавить еще одно static поле данных, и добавить в getInstance копирование config в это поле, но тогда ругается линковщик:

Как-то так:

class SettingInterface {
public:
    static SettingInterface& getInstance(QString const& filename) {
        static SettingInterface instance;
        static QString config = filename;
        SettingInterface::config1 = config;
        qDebug() << "Using: " << config;
        return instance;
    }



private:

    // Следующие 3 конструктора _не перегружать_ (singleton)
    SettingInterface();
    SettingInterface(SettingInterface const&);
    void operator=(SettingInterface const&);

    static QString config1;
};

error: undefined reference to `SettingInterface::config1'
★★

Последнее исправление: mono (всего исправлений: 1)

man cpp:

cpp - The C Preprocessor

anonymous
()

Попробуй что-нибудь типа этого.

#define DEFAULT_STRING "default_string"

class Singletone
{
public:
	Singletone* Instance()
	{
		if(m_instance==NULL) Singletone::createInstance(DEFAULT_STRING);
		return m_instance;
	}

	//тут обложится мутексами, чтобы одновременно могла выполнятся только одна ф-ия
	void createInstance(std::string string)
	{
		if(m_instance==NULL) m_instance = new Singletone(string);
	}
private:
	Singletone(std::string string)
	{
		m_string = string;
	}
	static Singletone* m_instance;
	std::string m_string;

}

P.S. ОСТОРОЖНО. Код писал прямо тут, могут быть ошибки и опечатки.

trex6 ★★★★★
()
Ответ на: комментарий от anonymous

Титиретики-архитектары с синглетонами не нужны.

А что предлагаеться юзать вместо? Неужели моноид в категории эндофункторов?

Ignatik
()

сделай глобальный статический указатель на свой объект и обёртку к нему которая его создаёт, если его нет, и не парь мозг.

и вообще, говорят синглтон - плохо.

m2.hpp:

namespace {

class Data
{
	public:
		Data(int i): i_(i) {}
		int get_i() {return i_;}
	private:
		int i_;
};

Data *ich_bin_ein_singleton = 0;

}

Data *data_factory(int i=42)
{
	if (ich_bin_ein_singleton) {
		return ich_bin_ein_singleton;
	} else {
		return ich_bin_ein_singleton = new Data(i);
	}
}
m2.cpp:
#include "m2.hpp"
#include <cstdio>

int f0()
{
	Data *p = data_factory(50);
	printf("%d\n", p->get_i());
}

int f1()
{
	Data *p = data_factory();
	printf("%d\n", p->get_i());
}

int main()
{
	f0();
	f1();
}

nanoolinux ★★★★
()

а зачем вообще делать config1 static?

сделай его обычным полем класса и потом в getInstance() сделай instance.config1 = config; qDebug() << config;

jeuta ★★★★
()
Ответ на: комментарий от trex6

Зачем createInstance public? Зачем NULL в C++? В C++11 синглтон майерса thread-safe, поэтому получается простой код


class Singletone
{
public:
	Singletone& Instance(const std::string & string)
	{
		static Singletone instance(string);
		return instance;
	}

private:
	Singletone(const std::string & string): string(string)
	{
	}
	std::string string;
}
Reset ★★★★★
()
Ответ на: комментарий от Reset

Тогда уж

--	Singletone& Instance(const std::string & string)
++	Singletone& Instance(const std::string & string = "")
а то постоянно придется строчку пустую самому писать.

trex6 ★★★★★
()
Ответ на: комментарий от aol

Третья ссылка жжот:

Поэтому все бегают, трясут писькой и радуются «У НАС ВСЁ ЧЕРЕЗ СИНГЛТОН И Я ТЕПЕРЬ ОРХИТЕКТАР!!!» и спрашивают «КАК МНЕ СДЕЛАТЬ ПОЛУТОН С ПОДСЧЁТОМ ССЫЛОК И ЧТОБЫ НИКТО НЕ УШЁЛ ОБИЖЕННЫМ?!!!»

- Ахуеть! Дайте пять!, - подхватывают одни.

- Какая у вас орхетектура, - изумляются другие.

- Как удобно! Мы всего лишь пишем Foo::GetInstance/*<Moo>*/().bar() - и всё работает, не то, что раньше!, - радуются программисты.

- И само создаёт объекты!!! И удаляет их!!!, - гудит толпа на многопоточной галёрке.

- И настраивается само, офтомотически!, - радуются конфигураторы и ревнители фабричного гудка.

- Теперь можно просто писать template<typename T> class Singleton, - снисходительно объясняет аффтар.

- И всё заипёццо.

anonymous
()

Так, на заметку. Напоролись в одном проекте: если используешь статик объект внутри функции, то он конструируется при первом обращении. И в многопоточной программе наступает многопоточный звездец. Так что лучше так не делать :-)

vega
()
Ответ на: комментарий от vega

статик объект внутри функции, то он конструируется при первом обращении

ВНЕЗАПНО! В первой главе любого учебника по C++, рассказывается о порядке конструирования локальных, глобальных и статических объектов.

DELIRIUM ☆☆☆☆☆
()

У наших нативных сегфолт-друзей IoC не в моде?

vertexua ★★★★★
()
Последнее исправление: vertexua (всего исправлений: 1)
Ответ на: комментарий от trex6

Вошел в стандарт с++11. Теперь его применять уж точно логичнее, чем абстрактный 0.

В плюсах 0 был не абстрактным. И Страуструп его разъяснял.

andreyu ★★★★★
()

SettingInterface instance
interface
instance

/0

anonymous
()
Ответ на: комментарий от aol

По ссылкам плохо скрываемые тонны БУГУРТА обиженника, которого не пускают в энтерпрайз.

anonymous
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.