Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > C/C++: Общие вопросы > Обращение к статичному экземпляру класса


Автор: InfMag 12.5.2012, 15:53
Доброго времени суток!

Я может недопонимаю концепт, но у меня возникла следующая загвоздка: я пишу некое приложение с использованием FMOD-либы. У меня есть класс, который будеть хранить и воспроизводить несколько звуков, каждый звук будет экземпляром класса. Реализация общения с FMOD будет вне класса абстрактна, но инициализировать новый звукопоток под каждый звук не практично и я делаю основной экземпляр класса FMOD-системы static. Но у меня возникает проблема, я не могу передать ссылку на адрес памяти от этого static экземпляра. Наглядно:

Так НЕ могу:
Код

//sound.hpp
#include "fmod/fmod.hpp"

class TickSound {
    static FMOD::System *fmod;
public:
    TickSound();
};

//sound.cpp
#include "sound.hpp"
#include "fmod/fmod.hpp"

TickSound::TickSound() {
    FMOD::System_Create(&this->fmod);
}

Отчёт об ошибке:
Код

src/sound.o: In function `TickSound::TickSound()':
sound.cpp:(.text+0x17): undefined reference to `TickSound::fmod'
collect2: выполнение ld завершилось с кодом возврата 1


А вот так (когда убираю static) МОГУ:
Код

//sound.hpp
#include "fmod/fmod.hpp"

class TickSound {
    FMOD::System *fmod;
public:
    TickSound();
};

//sound.cpp
#include "sound.hpp"
#include "fmod/fmod.hpp"

TickSound::TickSound() {
    FMOD::System_Create(&this->fmod);
}


Я не могу понять, почему? Кто-нибудь может прояснить? И как реализовать то, что я пытаюсь правильно? Заранее сердечно благодарю!

Автор: InfMag 12.5.2012, 16:23
И кстати! хочу сразу спросить: как в конструкторе определить, что класс уже инициализирован? Чтобы инициализировать его только один раз, а следующие сконструированные классы не пытались его инициализировать?

Автор: mes 12.5.2012, 16:26
статический дата-член в классе только объвляется.. для его определения в любом (одном) .cpp напишите 

Код

FMOD::System * TickSound::fmod;


Добавлено через 2 минуты и 21 секунду
Цитата(InfMag @  12.5.2012,  15:23 Найти цитируемый пост)
 а следующие сконструированные классы не пытались его инициализировать? 

1. инициализировать не в конструкторе, а явно в маин..
2. проверять на нуль, перед созданием
3. смотрите патерн синглетон.. 

Автор: InfMag 12.5.2012, 16:38
mes, спасибо! Теперь всё получилось:
Код

//sound.hpp
#include "fmod/fmod.hpp"

class TickSound {
    static FMOD::System *fmod;
public:
    TickSound();
};

//sound.cpp
#include "sound.hpp"
#include "fmod/fmod.hpp"

FMOD::System *TickSound::fmod;
bool inited = false;

TickSound::TickSound() {
    if (!inited) {
        FMOD::System_Create(&this->fmod);
        inited = true;
    }
}

Автор: mes 12.5.2012, 16:44
Цитата(InfMag @  12.5.2012,  15:38 Найти цитируемый пост)
  if (!inited) {

доп переменная не нужна.. достаточно проверки на нуль.. 

Автор: InfMag 12.5.2012, 16:44
mes, теперь вот так:
Код

//sound.hpp
#include "fmod/fmod.hpp"

class TickSound {
    static FMOD::System *fmod;
public:
    TickSound();
};

//sound.cpp
#include "sound.hpp"
#include "fmod/fmod.hpp"

FMOD::System *TickSound::fmod;

TickSound::TickSound() {
    if (this->fmod == NULL) FMOD::System_Create(&this->fmod);
}

Автор: mes 12.5.2012, 16:48
Цитата(InfMag @  12.5.2012,  15:44 Найти цитируемый пост)
 теперь вот так:

как минимум, я б проверку с инициализацией вынес в отдельную статическую функцию, которую уж вызывал бы из конструктора.. 

Автор: InfMag 12.5.2012, 22:13
mes, а для статической функции ведь недоступен this, к ней можно обращаться и без экземпляра класса, разве это применимо в данном контексте?

Автор: mes 12.5.2012, 22:33
Цитата(InfMag @  12.5.2012,  21:13 Найти цитируемый пост)
 а для статической функции ведь недоступен this, к ней можно обращаться и без экземпляра класса, разве это применимо в данном контексте? 

так fmod также статическая smile и this-> в примере абсолютно не нужен... эта возможность для унификации обращения к стат членам как к нестатическим.. 

Автор: InfMag 12.5.2012, 22:46
mes, действительно! Спасибо!

Автор: EvilsInterrupt 12.5.2012, 22:55
InfMag
Мне кажется mes прав и Вы пишете синглтон. Если мне кажется правильно и mes прав, то
может лучше так:
Код

class Singleton
{
public:
    static Singleton& getInstance()
    {
        static Singleton instance;
        std::cout << "getInstance()" << std::endl;
        return instance;
    }
private:
    Singleton(const Singleton&);

    Singleton()
    {
        std::cout << "Singleton()" << std::endl;
    }
};


Это более удачная конструкция, т.к. конструктор спрятан и ошибки компиляции предупредят о 
попытках создать еще один объект класса.

Автор: InfMag 12.5.2012, 23:34
EvilsInterrupt, нет, в моём случае экземпляров класса будет несколько.

Автор: mes 13.5.2012, 00:03
Цитата(InfMag @  12.5.2012,  22:34 Найти цитируемый пост)
нет, в моём случае экземпляров класса будет несколько. 

синглетон вместо статической фмод..

Добавлено через 4 минуты и 14 секунд
т.е. вынести фмод за пределы ТикСаунд

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)