Конструктор, деструктор и автоматический стек в C++

С удивлением узнал об интересном способе использования стека в нестандартных целях. Посмотрите внимательно на код ниже.

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

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

class Sample
{
public:
    Sample()
        : prevInst_s(curInst_s)
    {
        curInst_s = this;
    }
 
    ~Sample()
    {
        curInst_s = prevInst_s;
    }
 
    static Sample *instance()
    {
        return curInst_s;
    }
 
private:
    Sample *prevInst_s;
    static Sample *curInst_s;
};
 
Sample *Sample::curInst_s = NULL;

Пример использования такого функционала под катом. (в комментариях указано — какой instance сейчас текущий)

#include <stdio.h>
 
class Sample
{
public:
    Sample(const char *name)
        : name_(name)
        , prevInst_s(curInst_s)
    {
        curInst_s = this;
        printf("current: %s\n", name_);
    }
 
    ~Sample()
    {
        curInst_s = prevInst_s;
 
        if (curInst_s)
        {
            printf("restore: %s\n", curInst_s->name_);
        }
    }
 
    static Sample *instance()
    {
        return curInst_s;
    }
 
private:
    const char *name_;
    Sample *prevInst_s;
    static Sample *curInst_s;
};
 
Sample *Sample::curInst_s = NULL;
 
 
int main()
{
    /*
     *
     * Sample::instance() => NULL
     *
     */
    {
        Sample sampleA("A");
        /*
         *
         * Sample::instance() => A
         *
         */
        {
            Sample sampleB("B");
            /*
             *
             *  Sample::instance() => B
             *
             */
        }
        /* 
         * 
         * Sample::instance() => A
         *
         */
        {
            Sample sampleC("C");
            /*
             *
             * Sample::instance() => C
             *
             */
            {
                Sample sampleD("D");
                /*
                 *
                 * Sample::instance() => D
                 *
                 */
            }
            /*
             *
             * Sample::instance() => C
             *
             */
        }
        /*
         *
         * Sample::instance() => A
         *
         */
    }
    /*
     *
     * Sample::instance() => NULL
     *
     */
}

Добавить комментарий

Ваш e-mail не будет опубликован.