Форум программистов, компьютерный форум CyberForum.ru

Объект класса в динамической памяти - C++

Восстановить пароль Регистрация
 
lest_
0 / 0 / 0
Регистрация: 28.11.2013
Сообщений: 94
09.07.2014, 09:36     Объект класса в динамической памяти #1
Привет. Вот листинг:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
#include <iostream>
using namespace std;
 
class SimpleCat
{
public:
    SimpleCat(int age, int weight)
    {
        cout << "SimpleCat Constructor..." << endl;
        itsAge = age;
        itsWeight = weight;
    }
    ~SimpleCat() { cout << "In the DESTRUCTOR" << endl; }
    int GetAge()    { return itsAge; }
    int GetWeight() { return itsWeight; }
private:
    int itsAge;
    int itsWeight;
};
 
SimpleCat& func()
{
    SimpleCat* pFrisky = new SimpleCat(5,9);
    cout << "pFrisky: " << pFrisky << endl;
    return *pFrisky;
}
 
int main()
{
    SimpleCat& rCat = func();
    int age = rCat.GetAge();
    cout << "rCat is " << age << " years old!" << endl;
    cout << "&rCat: " << &rCat << endl;
 
    // Как бы избавиться от этой памяти?
    SimpleCat* pCat = &rCat;
    delete pCat; 
    pCat = 0;
    // Ой-ой, на что же теперь ссылается rCat?
 
    cout << &rCat << endl; // выводит тот же самый адрес
    cout << rCat.GetAge() << endl; // в Visual Studio 2010 выводит число -17891602
                                   // cpp.sh выводит 0 
 
    char response; std::cin >> response; // для задержки экрана
                            
    return 0;     
}
В функции main() необходимо освободить ненужный больше участок в динамической памяти. Для этого создаём указатель, инициализируем его адресом области в динамической памяти, а затем применяем к нему оператор delete (строки 36-38). После этого не понятно, на что ссылается rCat. Строчки 41 и 42 я сам добавил. В листинге в учебнике их не было. 2 разных компилятора выводят различный возраст удалённого кота (это надо воспринимать как "мусор"?). Автор говорит, что программа некоректная. И предлагает так решить проблему: "объявить объект класса SimpleCat в области динамической памяти (в теле функции func() ), но сделать это нужно так, чтобы функция func() вщзвращала указатель на данный объект. Затем, когда объект будет уже не нужен, его следует удалить в вызывающей функции при помощи оператора delete." Код не приведён. Я сам попробовал написать:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
#include <iostream>
using namespace std;
 
class SimpleCat
{
public:
    SimpleCat(int age, int weight)
    {
        cout << "SimpleCat Constructor..." << endl;
        itsAge = age;
        itsWeight = weight; 
    }
    ~SimpleCat() { cout << "In the DESTRUCTOR" << endl; }
    int GetAge()    { return itsAge; }
    int GetWeight() { return itsWeight; }
private:
    int itsAge;
    int itsWeight;
};
 
SimpleCat* func()
{
    SimpleCat* pFrisky = new SimpleCat(5,9);
    cout << "pFrisky: " << pFrisky << endl;
    return pFrisky;
}
 
int main()
{
    SimpleCat* pCat = func();
    int age = pCat->GetAge(); // аналогично команде: int age = (*pCat).GetAge();
    
    cout << "pCat is " << age << " years old!" << endl;
    cout << "pCat: " << pCat << endl;
 
    delete pCat; // освободили область динамической памяти 
    pCat = 0;
 
    cout << pCat << endl; // выводит на экран: 00000000
 
    char response; std::cin >> response; // для задержки экрана
                            
    return 0;     
}
Такой вариант правильный или нет? И почему первый вариант некорректный, если всё компилируется и запускается?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Vourhey
Почетный модератор
6468 / 2243 / 123
Регистрация: 29.07.2006
Сообщений: 12,635
09.07.2014, 09:58     Объект класса в динамической памяти #2
Цитата Сообщение от lest_ Посмотреть сообщение
// Ой-ой, на что же теперь ссылается rCat?
Ничего не поменялось. На ту же самую область памяти, куда и ссылался до этого.
Цитата Сообщение от lest_ Посмотреть сообщение
cout << &rCat << endl; // выводит тот же самый адрес
Так и должно быть.
Цитата Сообщение от lest_ Посмотреть сообщение
cout << rCat.GetAge() << endl; // в Visual Studio 2010 выводит число -17891602
* * * * * * * * * * * * * * * * * *// cpp.sh выводит 0
Все, что угодно может вывести, или, например, упасть с ошибкой доступа в "лучшем" случае. Зависит от реализации стандартной библиотеки, и от кода самой программы.

Добавлено через 3 минуты
Цитата Сообщение от lest_ Посмотреть сообщение
И почему первый вариант некорректный, если всё компилируется и запускается?
Даже не вдаваясь в объяснения, ты же сам написал:
Цитата Сообщение от lest_ Посмотреть сообщение
// в Visual Studio 2010 выводит число -17891602
* * * * * * * * * * * * * * * * * *// cpp.sh выводит 0
Это корректно, как ты считаешь, что у тебя выводится что-то левое?
Я могу писать почтовый клиент, а написать программу, которая отформатирует мне диск. Она будет компилироваться и запускаться. Ее можно считать корректным почтовым клиентом?
uglyPinokkio
325 / 228 / 41
Регистрация: 30.05.2014
Сообщений: 682
09.07.2014, 10:03     Объект класса в динамической памяти #3
Цитата Сообщение от lest_ Посмотреть сообщение
это надо воспринимать как "мусор"
Да. В худшем варианте он еще и некоторое время будет содержать вполне вменяемые данные.

Цитата Сообщение от lest_ Посмотреть сообщение
Такой вариант правильный или нет?
Неправильно использовать ссылку после разрушения объекта, на который она ссылается.
Ссылка - это еще одно имя того же самого объекта. Первый вариант синтаксически ошибок не содержит, ошибка в логике работы с памятью, такое компилятор обнаружить не в состоянии.
lest_
0 / 0 / 0
Регистрация: 28.11.2013
Сообщений: 94
12.07.2014, 08:35  [ТС]     Объект класса в динамической памяти #4
Цитата Сообщение от Vourhey Посмотреть сообщение
Это корректно, как ты считаешь, что у тебя выводится что-то левое?
Я могу писать почтовый клиент, а написать программу, которая отформатирует мне диск. Она будет компилироваться и запускаться. Ее можно считать корректным почтовым клиентом?
спасибо за ответ. а второй вариант (с указателем) правильно написан?
Yandex
Объявления
12.07.2014, 08:35     Объект класса в динамической памяти
Ответ Создать тему
Опции темы

Текущее время: 23:45. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru