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

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
 
HelicopterK52
660 / 203 / 28
Регистрация: 27.07.2016
Сообщений: 474
Завершенные тесты: 1
#1

Поменять make и release так, чтобы организовать правильное уничтожение объектов и освобождение памяти - C++

21.08.2016, 15:40. Просмотров 292. Ответов 15
Метки нет (Все метки)

Имеем код:
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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
#include <iostream>
 
 
struct Base
{
public:
    ~Base() { std::cout << "Base::~Base" << std::endl; }
};
 
 
 
struct First : Base
{
public:
    ~First() { std::cout << "First::~First" << std::endl; }
};
 
 
 
 
struct Second : Base
{
public:
    ~Second() { std::cout << "Second::~Second" << std::endl; }
};
 
 
 
Base *make()
{
    unsigned x = 0;
    if(!(std::cin >> x))
    {
        return nullptr;
    }
    if(x&1)
        return new First();
    return new Second(); 
}
 
 
 
 
void release(Base *ptr)
{
    delete ptr;
}
 
 
 
 
int main()
{
    while(true)
    {
        auto ptr1 = make();
        if(ptr1 == nullptr)
        {
            break;
        }
        //...
        release(ptr1);
    }
}
make создает объекты в зависимости от ввода пользователя, при ошибке ввода возвращает nullptr.
Если ввод удался, то создается соответствующий объект (это может быть расширено в дальнейшем).
В данном коде деструкторы не виртуальные, поэтому в release будет вызван лишь деструктор базового класса.

Задача:
Поменять make и release таким образом, чтобы организовать правильное уничтожение объектов и освобождение памяти.

Учтите, что сами классы, а также функцию main менять нельзя. Также в будущем планируется добавлять наследников Base, поэтому решение должно быть расширяемым без особого труда.
0
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
21.08.2016, 15:40
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Поменять make и release так, чтобы организовать правильное уничтожение объектов и освобождение памяти (C++):

Правильное освобождение памяти - C++
Есть код class Test { public: int **container; int counter = 0; Test(unsigned int size) { container = new int*;

Правильное освобождение памяти - C++
Здрасти. Двумерный динам. массив: int** matr=new int*; for (int i=0; i&lt;rows; ++i) matr=new int; ...

Правильное освобождение памяти при std::vector - C++
vector&lt;Worker*&gt; workers; workers.push_back(new Worker(&quot;Jack&quot;, 1000)) Как теперь правильно освободить память? Как я понял у...

Освобождение памяти динамически созданных объектов - C++
Подскажите, есть к примеру три класса: Class1, Class2, Class3. В Class2 имеется метод, в котором динамически создаю объекты класса...

Освобождение памяти для объектов производного класса - C++
Всем привет. Не могу найти инфу в интернете, всё перерыл, но понял что случай специфичный у меня. Придумал себе конструкцию, но не уверен,...

Освобождение памяти из под Объектов в статическом массиве указателей - C++
Всем добрый вечер! Решил расширить программу из книжки Лафорте Р. ООП в С++ стр. 574 путем добавления функции удаления данных о конкретном...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
obivan
Падаван С++
402 / 222 / 58
Регистрация: 11.11.2014
Сообщений: 773
Завершенные тесты: 2
21.08.2016, 15:50 #2
HelicopterK52,
Кликните здесь для просмотра всего текста

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
49
50
51
52
53
54
55
56
57
#include <iostream>
#include <memory>
struct Base
{
public:
    ~Base() { std::cout << "Base::~Base" << std::endl; }
};
 
struct First : Base
{
public:
    ~First() { std::cout << "First::~First" << std::endl; }
};
 
struct Second : Base
{
public:
    ~Second() { std::cout << "Second::~Second" << std::endl; }
};
 
std::shared_ptr<Base> make()
{
    unsigned x = 0;
    if (!(std::cin >> x))
    {
        return nullptr;
    }
    if (x & 1)
        return std::shared_ptr<Base>(new First());
    return std::shared_ptr<Base>(new Second());
}
 
 
 
 
void release(std::shared_ptr<Base> ptr)
{
    ptr.reset();
}
 
 
int main()
{
    int x = 0;
    while (x < 5)
    {
        auto ptr1 = make();
        if (ptr1 == nullptr)
        {
            break;
        }
        //...
        release(ptr1);
        x++;
    }
    system("pause");
}
0
HelicopterK52
660 / 203 / 28
Регистрация: 27.07.2016
Сообщений: 474
Завершенные тесты: 1
21.08.2016, 15:51  [ТС] #3
obivan, +.
Но вот теги можно было бы поставить
0
obivan
Падаван С++
402 / 222 / 58
Регистрация: 11.11.2014
Сообщений: 773
Завершенные тесты: 2
21.08.2016, 15:52 #4
HelicopterK52, забыл
0
HelicopterK52
660 / 203 / 28
Регистрация: 27.07.2016
Сообщений: 474
Завершенные тесты: 1
21.08.2016, 15:59  [ТС] #5
Кликните здесь для просмотра всего текста
obivan, только у Вас функция release совсем бесполезная. В параметрах - копия указателя, так что reset ни на что не повлияет. Уничтожение будет происходить в конце каждой итерации цикла в main. В данном случае это не страшно, но всё же.
1
obivan
21.08.2016, 16:01
  #6

Не по теме:

HelicopterK52, а, точно, спасибо что заметили

0
Babysitter
80 / 107 / 35
Регистрация: 23.11.2015
Сообщений: 332
Завершенные тесты: 1
21.08.2016, 19:15 #7
а я подумал про что-то такое и дооолго костылил
Кликните здесь для просмотра всего текста

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
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
#include <iostream>
 
struct Base
{
public:
    virtual void foo() {}
    ~Base() { std::cout << "Base::~Base" << std::endl; }
};
 
struct First : Base
{
public:
    void foo() override { std::cout << "First::foo" << std::endl; }
    ~First() { std::cout << "First::~First" << std::endl; }
};
 
struct Second : Base
{
public:
    void foo() override { std::cout << "Second::foo" << std::endl; }
    ~Second() { std::cout << "Second::~Second" << std::endl; }
};
 
// ugly
struct Wrapper
{
    enum class Type{ first, second };
    Wrapper(Base* base, Type type) : empty(false), type_(type), base_(base)  {}
    ~Wrapper() {
        switch(type_)
        {
            case Type::first:
                delete dynamic_cast<First*>(base_);
                break;
            case Type::second:
                delete dynamic_cast<Second*>(base_);
                break;
        }
    }
    // hack
    Wrapper(std::nullptr_t) : empty(true) {}
    bool operator==(std::nullptr_t) { return empty; }
    Base* operator->() { return base_; }
    Base& operator*() { return *base_; }
private:
    bool empty;
    Type type_;
    Base* base_;
};
bool operator==(std::nullptr_t, Wrapper& x) { return x == nullptr; }
 
Wrapper make()
{
    unsigned x = 0;
    if(!(std::cin >> x))
    {
        return nullptr;
    }
    if(x&1)
        return Wrapper{new First{}, Wrapper::Type::first};
    return Wrapper{new Second{}, Wrapper::Type::second}; 
}
 
void release(Wrapper&) {}
 
int main()
{
    while(true)
    {
        auto ptr1 = make();
        if(ptr1 == nullptr)
        {
            break;
        }
        ptr1->foo();
        release(ptr1);
    }
}
нужно зашаблонить еще
0
avgoor
909 / 544 / 118
Регистрация: 05.12.2015
Сообщений: 1,510
22.08.2016, 17:07 #8
obivan, HelicopterK52, Вы сами-то этот код запускали? Как умный указатель сделает из невиртуального деструктора виртуальный?
0
obivan
Падаван С++
402 / 222 / 58
Регистрация: 11.11.2014
Сообщений: 773
Завершенные тесты: 2
22.08.2016, 17:20 #9
avgoor, http://stackoverflow.com/questions/3...ared-ptr-magic

Добавлено через 13 секунд
запустите то код и проверьте
0
HelicopterK52
660 / 203 / 28
Регистрация: 27.07.2016
Сообщений: 474
Завершенные тесты: 1
22.08.2016, 17:22  [ТС] #10
Цитата Сообщение от avgoor Посмотреть сообщение
Вы сами-то этот код запускали?
А Вы?
http://rextester.com/YCL74424
Цитата Сообщение от avgoor Посмотреть сообщение
Как умный указатель сделает из невиртуального деструктора виртуальный?
У shared_ptr под капотом некий "хелпер", который знает какой объект внутри, так что всё нормально будет.
То есть shared_ptr не сделает деструктор виртуальным, он лишь произведет правильное уничтожение объекта.
Можете поизучать соответствующую литературу, документацию.
0
Ferrari F1
=^_^=
571 / 458 / 94
Регистрация: 27.01.2015
Сообщений: 2,696
Записей в блоге: 1
Завершенные тесты: 1
22.08.2016, 17:28 #11
HelicopterK52, не осилил, лень читать такую тягомотину, старайся сделать задачку максимально сжатой по коду (10 строк максимум) и вообще по объему.

И тогда прочтение мною твоего поста обеспечено.
0
HelicopterK52
660 / 203 / 28
Регистрация: 27.07.2016
Сообщений: 474
Завершенные тесты: 1
22.08.2016, 17:31  [ТС] #12
Цитата Сообщение от Ferrari F1 Посмотреть сообщение
не осилил, лень читать такую тягомотину, старайся сделать задачку максимально сжатой по коду
Не осилил - не лезь.
Цитата Сообщение от Ferrari F1 Посмотреть сообщение
И тогда прочтение мною твоего поста обеспечено.
Да мне как-то всё равно, прочитаешь ты его или нет. Надеюсь, я понятно выразился - ты не пуп земли. Так что учти это, когда следующий пост будешь писать. Как говорится, не указывайте мне что делать и...
0
Ferrari F1
22.08.2016, 17:34
  #13

Не по теме:

HelicopterK52, воу-воу, палехче, бро) Давай только без резкостей. Это сейчас нужно меньше всего
но читать, а уж тем более вникать в конце рабочего дня в длинный пост на самом деле не по кайфу

0
HelicopterK52
22.08.2016, 17:34  [ТС]
  #14

Не по теме:

Цитата Сообщение от Ferrari F1 Посмотреть сообщение
Давай только без резкостей. Это сейчас нужно меньше всего

0
avgoor
909 / 544 / 118
Регистрация: 05.12.2015
Сообщений: 1,510
22.08.2016, 17:46 #15
HelicopterK52, obivan, Тьфу, блин, ступил. Обычно unique_ptr возвращается, а я сейчас "выхожу из состояния глубокой отладки", вот и заклинило.
0
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
22.08.2016, 17:46
Привет! Вот еще темы с ответами:

Правильное уничтожение объекта - C++
Добрый день, имеется следующий вопрос! Есть некоторый класс, который на вход (в конструктор) получает аргументы, после чего парсит их....

Уничтожение указанных объектов - C++
Здравствуйте. Не могу разобраться как реализовать следующее: Имеется класс Human, далее необходимо сделать класс Murderer который по...

резервирование памяти/освобождение памяти для трехмерного массива - C++
Необходимо создать трехмерный массив (A), в котором элементы вдоль направления Z выли бы выровнены по 16 байт. Есть две проблемы: ...

Виртуальный деструктор и уничтожение объектов - C++
Приветствую всех. вопрос наверное простой так, что не ругайтесь. столкнулся с проблемой освобождения памяти. вот пример кода: ...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
22.08.2016, 17:46
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru