Объект находиться в стеке или в динамической памяти?

Тема в разделе "LANGS.C", создана пользователем letopisec, 26 ноя 2009.

  1. letopisec

    letopisec New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2004
    Сообщения:
    228
    Можно ли как-то определить где был создан объект, в стеке или в хипе при помощи оператора new?

    Надо чтобы реализовать вот такую идею:

    class Base
    {
    public:
    Base () {}
    virtual ~Base ()
    {
    std::vector<Base*>::iterator i;
    for (i = children.begin(); i != children.end(); ++i)
    if ((*i)->in_stack())
    delete *i;
    }

    Base *attach (Base* obj)
    {
    children.push_back(obj);
    return this;
    }

    size_t dump (void* ptr)
    {
    return ptr;
    }

    private:
    std::vector<Base*> children;
    };

    size_t func1 (char *ptr)
    {
    Base obj;
    Base obj1;
    obj.attach(&obj1);
    return obj.dump(ptr);
    }

    Base * create_tree ()
    {
    Base *obj = new Base;
    Base *obj1 = new Base;
    return obj->attach(obj1);
    }
     
  2. o14189

    o14189 New Member

    Публикаций:
    0
    Регистрация:
    19 июл 2009
    Сообщения:
    320
    только средствами ОС походу
     
  3. W4FhLF

    W4FhLF New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2006
    Сообщения:
    1.050
    Вообще похоже на не очень удачную архитектуру. Плохая идея добавлять указатель на локальный объект.

    А так... кто тебе мешает добавить флаг bool isLocal в класс? Выставить по дефолту true. Потом можно писать:

    Base obj;
    ...
    Base *obj = new Base(false);
     
  4. letopisec

    letopisec New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2004
    Сообщения:
    228
    W4FhLF

    так делать не хочется.

    А можно хотя бы запретить создание локально, чтобы можно было создать объект только оператором new?
     
  5. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    запротектидь деструктор?
     
  6. W4FhLF

    W4FhLF New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2006
    Сообщения:
    1.050
    n0name, тогда уж конструктор.

    Можно сделать так:

    Код (Text):
    1. class Base:
    2. {
    3. public:
    4.      static Base* createBase(); { return new Base(); }
    5. private:
    6.     Base(); // private ctor
    7. };
    8.  
    9. ...
    10.  
    11. Base* obj = createBase();
    А вообще у меня ощущение, что задачу надо решать иначе. :) Только я не совсем понял суть задачи.
     
  7. W4FhLF

    W4FhLF New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2006
    Сообщения:
    1.050
    А можно ещё wrapper написать:

    Код (Text):
    1. template<typename T>
    2. class Wrapper
    3. {
    4. public:
    5.   Wrapper()
    6.   { data = new T(); }
    7.   ~Wrapper()
    8.   { delete data; }
    9.   T* value() const
    10.   { return data; }
    11. private:
    12.  T *data;
    13. };
    14.  
    15. ...
    16.  
    17. Base* = Wrapper<Base>().value();
     
  8. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    тогда не сможем создавать с помощью new, чего требует автор :)
    А с запротекченным деструктором мы не сможем вызывать delete, а new спокойно.
     
  9. W4FhLF

    W4FhLF New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2006
    Сообщения:
    1.050
    n0name, это типа да здравствуют утечки?)
     
  10. n0name

    n0name New Member

    Публикаций:
    0
    Регистрация:
    5 июн 2004
    Сообщения:
    4.336
    Адрес:
    Russia
    ну дык, паблик метод DeleteObject() написать :)
     
  11. W4FhLF

    W4FhLF New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2006
    Сообщения:
    1.050
    Kучше в таком случае использовать умные указатели. Например boost::shared_ptr.
     
  12. letopisec

    letopisec New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2004
    Сообщения:
    228
    W4FhLF
    Задача вот какая. Есть примерно штук 25 классов (потом это будет расширяться) происходящих от одного базового имеющего виртуальные функции (ну все как обычно). Эти объекты мне надо связать в деревья а потом подампить в файлы.

    Создание дерева должно примерно выглядеть так:

    Tree tree1 ("file1");
    Tree tree2 ("file2");
    Tree tree3 ("file3");
    Tree tree4 ("file4");

    Base b1* = create_topology1();
    Base b2* = create_topology2();
    Base b3* = create_topology3();
    Base b4* = create_topology4();

    Flower flower;

    tree->attach(b2)->attach(b1)->attach(b2)->attach(b2);
    tree.dump ("file1");

    tree1.attach(b1)->attach(b1)->attach(b2)->attach(b3);
    tree2.attach(b2)->attach(b3)->attach(b4)->attach(b1);
    tree1.dump();
    tree2.dump();

    b2->attach(&flower);
    tree3.attach(b1)->attach(b1)->attach(b2)->attach(b3)->attach(b2)->attach(b3);

    flower->attach(b4).
    tree4.attach(b1)->attach(b2)->attach(flower);


    Ну вот примерно так. Причем все объекты происходят от одного. Т.е надо создать много сложных видов деревьев на основе более простых.

    Возникает вопрос как удалять ветки после того как они были созданы create_topology(). - Ответ делетить объекты которые были созданы оператором new. Но тогда как же flower? - надо тоже создавать путем new - но чтобы обязать к этому надо прятать конструктор и создавать отдельными методами.

    Вот в этом и сосоит моя задача. Как ее по-другому решать (имеется ввиду подход) я хз...
     
  13. W4FhLF

    W4FhLF New Member

    Публикаций:
    0
    Регистрация:
    3 дек 2006
    Сообщения:
    1.050
    letopisec, хм, наверное лучше использовать умные указатели (boost::shared_ptr). C удалением париться не надо будет и локально объект обёрнутый в умный указатель не создашь. Overhead по производительности не будет.

    просто сделай typedef для Base после объявления:

    Код (Text):
    1. typedef boost::shared_ptr<Base> BasePtr;
    2. ...
    3.  
    4. BasePtr(new Flower());
     
  14. nop_

    nop_ New Member

    Публикаций:
    0
    Регистрация:
    21 июн 2007
    Сообщения:
    61
    Для стековых объектов можно в конструктор shared_ptr передавать пустой deleter.
     
  15. letopisec

    letopisec New Member

    Публикаций:
    0
    Регистрация:
    8 авг 2004
    Сообщения:
    228
    W4FhLF
    Вообще я об этом уже думал. В принципе, как вариант да.
    А что если как-нить в сторону перегрузки new?

    Код (Text):
    1. void* Base::operator new(size_t bytes)
    2. {
    3.     void * ptr = ::operator new (bytes);
    4.     Base *base = (Base*)ptr;
    5.     Base->is_dynamic = 0x33333333;
    6.     return ptr;
    7. }
    Только здесь непонятно, что делать в случае если объект создается локально, is_dynamic получается не инициализированной.
    Если использовать строго однопоточную модель, то можно завести в классе статическую переменную и сделать вот так: