Книги
чёрным по белому
Главное меню
Главная О нас Добавить материал Поиск по сайту Карта книг Карта сайта
Книги
Археология Архитектура Бизнес Биология Ветеринария Военная промышленность География Геология Гороскоп Дизайн Журналы Инженерия Информационные ресурсы Искусство История Компьютерная литература Криптология Кулинария Культура Лингвистика Математика Медицина Менеджмент Металлургия Минералогия Музыка Научная литература Нумизматика Образование Охота Педагогика Политика Промышленные производства Психология Путеводители Религия Рыбалка Садоводство Саморазвитие Семиотика Социология Спорт Столярное дело Строительство Техника Туризм Фантастика Физика Футурология Химия Художественная литература Экология Экономика Электроника Энергетика Этика Юриспруденция
Новые книги
Цуканов Б.И. "Время в психике человека" (Медицина)

Суворов С. "Танк Т-64. Первенец танков 2-го поколения " (Военная промышленность)

Нестеров В.А. "Основы проэктирования ракет класса воздух- воздух и авиационных катапульных установок для них" (Военная промышленность)

Фогль Б. "101 вопрос, который задала бы ваша кошка своему ветеринару если бы умела говорить" (Ветеринария)

Яблоков Н.П. "Криминалистика" (Юриспруденция)
Реклама

C++. Энциклопедия пользователя - Либерти Дж.

Либерти Дж. C++. Энциклопедия пользователя — Москва, 2001. — 581 c.
Скачать (прямая ссылка): enciklopediyapolzovatelya2001.djvu
Предыдущая << 1 .. 42 43 44 45 46 47 < 48 > 49 50 51 52 53 54 .. 280 >> Следующая

Указатель, указатель, указатель
Когда программа распределяет память из свободного хранилища (из кучи), то возвращается указатель. Хранить указатель обязательно. Если его потерять, то память нельзя будет удалить и появится ее утечка.
Когда данный блок памяти передается между функциями, кто-то будет владеть указателем. Обычно значение в блоке передается с использованием ссылок, и функция, которая создала память, будет ее и удалять. Но это общее правило.
100
Вопросы реализации
Часть II
Тем не менее, опасно, когда одна функция создает память, а другая ее освобождает. Неоднозначность в том, кто владеет указателем, может привести к одной из двух проблем: забывают удалить указатель, или он удаляется дважды. Любой вариант может привести к серьезным ошибкам в программе. Безопаснее создавать функции так, чтобы они удаляли ту память, которую создают.
СОВЕТ
Если вы создаете функцию, которая должна создать память и затем передать ее обратно в вызывающую функцию, то рассмотрите возможность изменения интерфейса. Заставьте вызывающую функцию распределять память и затем передавать ее в функцию по ссылке. В результате такого подхода все управление памятью перемещается из вашей программы обратно в функцию, которая подготовлена для ее удаления.
Указатели и исключения
Управление памятью объектов в куче становится особенно проблематичным при наличии исключений. Рассмотрим пример, показанный в листинге 4.6.
Листинг 4.6. Объекты в куче и исключения___________________________________________________________________
#include <iostream.h>
class myException {
public:
char * errorMsgO { return "Oops."; }
) ;
class Point {
public:
Point (int x, int y):myX(x), myY(y)
{
cout « "Point constructor called"« endl;
)
Point (const Point & rhs): myX(rhs.myX),
myY(rhs.myY){ cout « "Point copy constructor called" « endl;)
~Point(){ cout « "Point destructor called" « endl;} int GetX() const { return myX; ) void SetX(int x) { myX = x; ) int GetY() const { return myY; } void SetY(int y) { myY = y; ) private:
int myX; int myY;
>;
class Rectangle
<
public:
Rectangle(Point upperLeft, Point lowerRight): myUpperLeft ( new Point(upperLeft)), myLowerRight(new Point(lowerRight))
{)
Rectangle(Point * pOpperLeft, Point * pLowerRight): myUpperLeft ( new Point(*pOpperLeft)), myLowerRight(new Point(*pLowerRight))
{}
Rectangle(int upperLeftX, int upperLeftY, int lowerRightX, int lowerRightY): myUpperLeft(new Point(upperLeftX,upperLeftY)), myLowerRight(new Point(lowerRightX,lowerRightY))
U
Управление памятью 1 101
Глава 4 ¦ 1U I
Rectangle( const Rectangle & rhs ) :
myUpperLeft(new Point(‘myUpperLeft)) , myLowerRight(new Point(‘myLowerRight))
{)
-Rectangle()
{
cout « "In Rectangle's destructor" « endl; delete myUpperLeft; delete myLowerRight;
>
int GetWidth() { return myLowerRight->GetX() - myUpperLeft->GetX() ; )
int GetHeightO ( return myLowerRight->GetY() - myUpperLeft->GetY(); )
void DangerousMethod() { throw myException(); }
private:
Point * myUpperLeft;
Point * myLowerRight;
};
int main()
{
try
{
cout « "Begin round 1..." « endl;
Point * pUL = new Point (0,0) ;
Point * pLR = new Point (20,30) ;
Rectangle myRectangle(pUL, pLR); int w = myRectangle .GetWidth () ; int h = myRectangle.GetHeight();
cout « "the Rectangle is " « w « " by " « h « endl; delete pUL; delete pLR;
)
catch ( myException & e )
{
cout « "caught exception: " « e.errorMsgO « "\n\n" « endl;
)
try
<
cout « "Begin round 2..." « endl;
Point * pUL = new Point (0,0) ;
Point * pLR = new Point (20,30) ;
Rectangle myRectangle(pUL, pLR); int w = myRectangle.GetWidth(); int h = myRectangle.GetHeight();
cout « "the Rectangle is " « w « " by " « h « endl; myRectangle.DangerousMethod(); delete pUL; delete pLR;
)
catch ( myException & e )
{
cout « "caught exception: " « e.errorMsgO « "\n\n" « endl;
}
return 0;
Ниже представлен вывод, порожденный этим программным кодом:
102
Вопросы реализации
Часть II
Begin round 1...
Point constructor called Point constructor called Point copy constructor called Point copy constructor called the Rectangle is 20 by 30 Point destructor called Point destructor called In Rectangle's destructor Point destructor called Point destructor called Begin round 2...
Point constructor called Point constructor called Point copy constructor called Point copy constructor called the Rectangle is 20 by 30 In Rectangle's destructor Point destructor called Point destructor called caught exception: Oops.
В данном простом примере создается пара объектов Point, которые затем используются (путем создания копии) для получения прямоугольника. После этого объекты Point можно удалить. При втором проходе вызывается метод DangerousMethod(), который возбуждает исключение.
Подсчитайте конструкторы и деструкторы. В первом проходе имеет место смещение деструктора по отношению к каждому вызову конструктора. Поскольку во втором проходе возбуждается исключение, то операторы delete никогда не выполняются и неизбежен расход памяти.
Предыдущая << 1 .. 42 43 44 45 46 47 < 48 > 49 50 51 52 53 54 .. 280 >> Следующая