Можно ли как-то определить где был создан объект, в стеке или в хипе при помощи оператора 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); }
Вообще похоже на не очень удачную архитектуру. Плохая идея добавлять указатель на локальный объект. А так... кто тебе мешает добавить флаг bool isLocal в класс? Выставить по дефолту true. Потом можно писать: Base obj; ... Base *obj = new Base(false);
W4FhLF так делать не хочется. А можно хотя бы запретить создание локально, чтобы можно было создать объект только оператором new?
n0name, тогда уж конструктор. Можно сделать так: Код (Text): class Base: { public: static Base* createBase(); { return new Base(); } private: Base(); // private ctor }; ... Base* obj = createBase(); А вообще у меня ощущение, что задачу надо решать иначе. Только я не совсем понял суть задачи.
А можно ещё wrapper написать: Код (Text): template<typename T> class Wrapper { public: Wrapper() { data = new T(); } ~Wrapper() { delete data; } T* value() const { return data; } private: T *data; }; ... Base* = Wrapper<Base>().value();
тогда не сможем создавать с помощью new, чего требует автор А с запротекченным деструктором мы не сможем вызывать delete, а new спокойно.
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 - но чтобы обязать к этому надо прятать конструктор и создавать отдельными методами. Вот в этом и сосоит моя задача. Как ее по-другому решать (имеется ввиду подход) я хз...
letopisec, хм, наверное лучше использовать умные указатели (boost::shared_ptr). C удалением париться не надо будет и локально объект обёрнутый в умный указатель не создашь. Overhead по производительности не будет. просто сделай typedef для Base после объявления: Код (Text): typedef boost::shared_ptr<Base> BasePtr; ... BasePtr(new Flower());
W4FhLF Вообще я об этом уже думал. В принципе, как вариант да. А что если как-нить в сторону перегрузки new? Код (Text): void* Base::operator new(size_t bytes) { void * ptr = ::operator new (bytes); Base *base = (Base*)ptr; Base->is_dynamic = 0x33333333; return ptr; } Только здесь непонятно, что делать в случае если объект создается локально, is_dynamic получается не инициализированной. Если использовать строго однопоточную модель, то можно завести в классе статическую переменную и сделать вот так: