Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: не могу придумать решение  (Прочитано 8519 раз)
0 Пользователей и 4 Гостей смотрят эту тему.
Алик
Постоялец

kz
Offline Offline

« : 08-11-2005 13:57 » new

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

вроде нефиг делать, а как начинаю искать красивое решение (удобное в использовании), да и вообще, любое  - ум за разум заходит.
мож, кто чего подскажет?
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 08-11-2005 14:04 » 

мысль: надо создать в классе  некий статик флаг

static bool flag=false;

и переменные класса
int N; //
bool b_N_inited;

в конструкторе класса:

if(!flag)
{
   flag=true;
   b_N_inited=true;
   N=/*инициализация*/
}
else
{
   b_N_inited=false;
}

то есть в результате в кажном экземпляре класса флаг b_N_inited будет указывать - инициализирована N или нет
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #2 : 08-11-2005 14:08 » 

Код:
class COnce
{
int N;
bool b_N_inited;

COnce()
{
static bool flag=false;
if(!flag)
{
flag=true;
b_N_inited=true;
N=1000;
}
else
{
N=-1;
b_N_inited=false;
}
}
};
Записан

npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #3 : 08-11-2005 16:15 » 

В классе надо завести статическое поле -- счётчик объектов класса, который увеличивается на 1 при каждом вызове конструктора и уменьшается на 1 при каждом вызове деструктора.  Конструктор класса создаёт нужный тебе "полустатический" член только в том случае, когда счётчик равен 0, деструктор уничтожает "полустатический" член, когда счётчик после уменьшения равен 0.

Пример: класс Object с разделяемым  динамически управляемым ресурсом типа Resource
Код:
// простейший ресурс
class Resource {
public:
    Resource() { std::cout << "Resource allocated" << std::endl; }
    ~Resource() { std::cout << "Resource released" << std::endl; }
};

class Object {
private:
    static unsigned int objcount;      // счётчик "живых" объектов
    static Resource * resource;        // "полустатический" член класса
public:
    Object() {
        if (objcount == 0) resource = new Resource();  // захватить ресурс только при создании первого объекта
        ++ objcount; /* инициализация объекта */
        std::cout << "Object created: number of objects " << objcount + 1 << std::endl;
    }
    ~Object() {
        -- objcount; /* очистка объекта */
        std::cout << "Object destroyed: number of objects " << objcount << std::endl;
        if (objcount == 0) {                        // освободить ресурс только при удалении последнего объекта
            delete resource;
            resource = 0;
        }
    }
};

Пример использования
Код:
unsigned int Object::objcount = 0;
Resource * Object::resource = 0;

int main()
{
    std::cout << "Before creating objects" << std::endl;
    Object * o1 = new Object();
    Object * o2 = new Object();
    Object * o3 = new Object();

    delete o1;
    delete o2;
    delete o3;
    std::cout << "After destroying objects" << std::endl;
    return 0;
}

После компиляции и исполнения примера на консоль выводятся строки
Цитата
Before creating objects
Resource allocated
Object created: number of objects 2
Object created: number of objects 3
Object created: number of objects 4
Object destroyed: number of objects 2
Object destroyed: number of objects 1
Object destroyed: number of objects 0
Resource released
After destroying objects

Видно, что ресурс захватывается при создании первого объекта, и освобождается при удалении последнего. Порядок создания и удаления объектов роли не играет.
« Последнее редактирование: 08-11-2005 16:21 от npak » Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
Алик
Постоялец

kz
Offline Offline

« Ответ #4 : 08-11-2005 17:13 » 

Спасибо за идеи. Но это - не совсем то, что я ищу.
код должен быть пригоден для повторного использования:
во-первых, заранее не известен тип полуконстантной переменной.
во-вторых, нужно, чтобы код было легко встроить в программу. в смысле, конечно, не составит труда ввести переменную-счетчик и вписать соответствующий код в деструктор класса. но это же лень. да и какого черта писать от раза к разу одно и то же.
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 09-11-2005 05:38 » 

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

если тип заранее неизвестен, юзай void*

встроить код можно через copy-paste Ага
Записан

npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #6 : 09-11-2005 11:17 » 

код должен быть пригоден для повторного использования:
Цитата

Возьми предложенное и адаптируй под свои условия.  Не бывает универсальных решений. 

во-первых, заранее не известен тип полуконстантной переменной.

На такой случай в С++ припасены шаблоны (template)

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

Иногда так бывает, что для того, чтобы воспользоваться советами умных людей, надо немного подумать своей головой.  Подсказка -- для членов класса деструкторы вызываются автоматически.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines