незванный гость писал(а):
Если Вас так пугают незамеченные ошибки в куче, есть стандартное решение - временный custom allocator. Который a) ведет список всех захваченных и возвращенных областей памяти (и тем самым, проверяет утечки памяти, двойные возвращения и т.п.) и b) контролирует (или пытается контролировать) переполнение при помощи создания буферных зон с сигнатурами. Ловит проблемы куда лучше стековых переменных, дает более осмысленную диагностику, и исчезает по мановению волшебного #define DEBUG_OFF. Ресурсы, конечно, поджирает, так при отладке же...
Ладно, оставим Security в покое... Слава богу, я про "них" знаю только по наслышке (пока что)
. Говоря о временном custum allocator, Вы имеете в виду перегрузку операторов new и delete или что-то другое? Где нибудь в литературе есть реализация того, как это делается и внятное описание?
Что касается вопроса создания объектов - в стеке или в куче, я пока прихожу к выводу, что в куче надо создавать крупные объекты (те, которые невыгодно копировать при присваивании). Остальные же (наподобие небольших строк, списков) лучше размещать в стеке.
Может быть, тут вопрос даже не в том, где реально будет выделена память, а как нам лучше объявлять экземпляр объекта.
Например:
Класс, представляющий собой координаты точки
Код:
class TCoord
{
int x;
int y;
public:
TCoord(){};
.....
};
Класс "линия" #1:
Код:
class TLine1
{
softarray<TCoord *> *line;
.....
};
Класс "линия" #2:
Код:
class TLine2
{
softarray<TCoord> *line;
.....
};
Класс "линия" #3:
Код:
class TLine3
{
softarray<TCoord> line;
.....
};
softarray - это шаблон класса, который реализует "безопасные" массивы объектов того типа, который является параметром этого шаблона. Сначала я не хотел его описывать, но уж на всякий случай тоже приведу:
Код:
template <class Type>
class softarray //Dynamic array of Type
{
public:
softarray(); //Конструктор
softarray(const softarray<Type> &dv);//Конструктор копирования.
int setlength(int length); //установить длину массива
int add(Type el);//добавить элемент массива.
int length(void) const;//Получить длину массива
~softarray(); //Деструктор
softarray<Type> &operator = (const softarray<Type> &dv);//Присваивание
Type &operator [](int index);//Оператор индексирования массива
operator Type*(void) const; //Оператор преобразования указателя.
private:
Type *ptr;
int len;
};
Какая из реализаций класса линии удобнее? Я прихожу к выводу, что третья... Если после этого мы создадим экземпляр класса TLine3 динамически через new, то он весь (и все его поля) будет размещатся в куче, и нас не побьют палками по пяткам!