Есть полиморфная иерархия классов. Необходимо запретить создание объектов классов этой иерархии в памяти стека(например: Type ob; // должно приводить к ошибке компиляции), а разрешить только в динамической(с помощью new)? При этом производные классы изменять недопустимо, можно только базовый.
Re: Как запретить создание объектов в памяти стека.
Здравствуйте, Аноним, Вы писали:
А>Есть полиморфная иерархия классов. Необходимо запретить создание объектов классов этой иерархии в памяти стека(например: Type ob; // должно приводить к ошибке компиляции), а разрешить только в динамической(с помощью new)? При этом производные классы изменять недопустимо, можно только базовый.
Перенести деструктор в защищенную секцию
Re[2]: Как запретить создание объектов в памяти стека.
Здравствуйте, placement_new, Вы писали:
_>Здравствуйте, Аноним, Вы писали:
А>>Есть полиморфная иерархия классов. Необходимо запретить создание объектов классов этой иерархии в памяти стека(например: Type ob; // должно приводить к ошибке компиляции), а разрешить только в динамической(с помощью new)? При этом производные классы изменять недопустимо, можно только базовый.
_>Перенести деструктор в защищенную секцию
в protected? Тогда в производных классах также нужно сделать деструктор protected, но согласно начальному условию, изменять производные классы нельзя. А если в потомках оставить деструктор public, то объекты можно создавать в стековой памяти.
Re[2]: Как запретить создание объектов в памяти стека.
Здравствуйте, Аноним, Вы писали:
А>При этом производные классы изменять недопустимо, можно только базовый.
Спрячь наследников и предоставь фабрики, которые будут возвращать std::auto_ptr<Base>.
Тогда все клиенты отвалятся и будут вынуждены использовать фабрики =)
Re[4]: Как запретить создание объектов в памяти стека.
Здравствуйте, dabeat_bf, Вы писали:
_>это все зависит от того, как конструктор копирования будет выглядеть _>на самом деле задача не тривиальная, как следствие решение (если таковое есть) будет тоже извращенным
Насколько я знаю, нормального решения именно для иерархии при такой постановке нет.
Пока единственное хоть сколько-нибудь рабочее — заныкать иерархию и отдавать через фабрики. Тоже метод в общем-то.
А по поводу конструктора копии —
A(const A& other)
{
// ... здесь конструируем
// ... а потом - серпом по яйцам!
A* ptr = const_cast<A*>(&other);
delete A;
}
Это имеете ввиду?
Думаю, не нужно говорить, что случится, если кто-то, создавая иерархию, передаст туда временный объект...
Re[8]: Как запретить создание объектов в памяти стека.
Здравствуйте, Мишень-сан, Вы писали:
МС>А по поводу конструктора копии — МС>
МС>A(const A& other)
МС>{
МС> // ... здесь конструируем
МС> // ... а потом - серпом по яйцам!
МС> A* ptr = const_cast<A*>(&other);
МС> delete A;
МС>}
МС>
МС>Это имеете ввиду?
МС>Думаю, не нужно говорить, что случится, если кто-то, создавая иерархию, передаст туда временный объект...
я не говрил о конкретной реализации, но придумать что-то можно, например в вашем случае если передавать в конструктор копирования не константную ссылку, то временный объект туда никто не передаст, но опять таки нужно думать чтоб придумать что-то стоящее я просто предложил направление для размышления
Re[8]: Как запретить создание объектов в памяти стека.
class A
{
public:
static A * Create()
{
return new A();
}
protected:
A(A &a)
{
//копируем
//........
//........
//удаляем
A * a_ = &a;
delete a_;
};
A(const A & a)
{
//копируем
//........
//........
//и не удаляем
};
private:
A()
{
};
};
class B : public A
{
public:
B() : A(*A::Create())
{
};
};
Здравствуйте, Аноним, Вы писали:
А>Есть полиморфная иерархия классов. Необходимо запретить создание объектов классов этой иерархии в памяти стека(например: Type ob; // должно приводить к ошибке компиляции), а разрешить только в динамической(с помощью new)? При этом производные классы изменять недопустимо, можно только базовый.
А зачем всё это надо?
Можно, например, завести какой-нибудь объект, к которому у наследников нет доступа, и чисто-виртуальный метод, в реализации которого нужен доступ к этому объекту, ну и вперёд. Создавать объекты производных классов сможет только твоя фабрика
class CrazyFactory {
struct CSeed { };
template<typename T> class RealObject : public T {
CSeed CheckSeed( CSeed s ) { return s; }
};
public:
class Root {
public:
virtual ~Root() {};
private:
virtual CSeed CheckSeed( CSeed ) = 0;
};
template<typename T> Root* CreateNewObject() { return new RealObject<T>(); }
};
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
class CrazyFactory {
struct CSeed { };
template<typename T> class RealObject : public T {
CSeed CheckSeed( CSeed s ) { return s; }
};
public:
class Root {
public:
virtual ~Root() {};
private:
virtual CSeed CheckSeed( CSeed ) = 0;
};
template<typename T> T* CreateNewObject() { return new RealObject<T>(); }
};
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском
Все эмоциональные формулировки не соотвествуют действительному положению вещей и приведены мной исключительно "ради красного словца". За корректными формулировками и неискажённым изложением идей, следует обращаться к их автором или воспользоваться поиском