Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Блоги Сообщество Поиск Заказать работу  
 
0 / 0 / 0
Регистрация: 24.12.2021
Сообщений: 1

Умный указатель weak_ptr

12.07.2022, 02:35. Показов 1407. Ответов 0
Метки c++ (Все метки)

Студворк — интернет-сервис помощи студентам
Разработайте шаблонный класс Cache<Key, Value, ValueFactoryFn>, представляющий собой кэш объектов.
Реализуйте также недостающий функционал класса BookLoader, загружающий книги из хранилища unordered_map<string, string>. Этот класс играет роль фабрики, которую кэш использует для конструирования значений, если их в кэше нет.
Требования к классам
Класс Cache должен иметь метод GetValue, который возвращает указатель shared_ptr, ссылающийся на значение типа Value с ключом типа Key, а в случае отсутствия ключа должен создавать новое значение и возвращать указатель на него.

Используйте контейнер map или unordered_map для хранения содержимого кэша. В качестве значений примените weak_ptr<Value>. Тогда объекты автоматически будут удаляться из динамической памяти при отсутствии сильных ссылок на них.
Если оказалось, что слабая ссылка в кэше устарела, создайте объект заново, используя фабрику.
Чтобы BookLoader мог находить книги, которые появляются в хранилище, он должен хранить не копию хранилища книг, а константную ссылку на него.


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
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
#include <cassert>
#include <iostream>
#include <memory>
#include <string>
#include <string_view>
#include <unordered_map>
 
template <typename Key, typename Value, typename ValueFactoryFn>
class Cache {
public:
    // Создаёт кэш инициализированный фабрикой значений, созданной по умолчанию
    Cache() = default;
 
    // Создаёт кэш, инициализированный объетом, играющим роль фабрики,
    // создающей (при помощи operator() значение по его ключу)
    // Фабрика должна вернуть shared_ptr<Value> либо unique_ptr<Value>.
    // Пример использования:
    // shared_ptr<Value> value = value_factory(key);
    explicit Cache(ValueFactoryFn value_factory) {
        // Реализуйте конструктор самостоятельно
    }
 
    // Возвращает закешированное значение по ключу. Если значение отсутствует или уже удалено,
    // оно должно быть создано с помощью фабрики и сохранено в кэше.
    // Если на объект нет внешних ссылок, он должен быть удалён из кэша
    std::shared_ptr<Value> GetValue(const Key& key) {
        (void) key;
        // Заглушка. Реализуйте метод самостоятельно
        return nullptr;
    }
};
 
// Пример объекта, находящегося в кэше
class Object {
public:
    explicit Object(std::string id)
        : id_(std::move(id))  //
    {
        using namespace std;
        cout << "Object '"sv << id_ << "' has been created"sv << endl;
    }
 
    const std::string& GetId() const {
        return id_;
    }
 
    ~Object() {
        using namespace std;
        cout << "Object '"sv << id_ << "' has been destroyed"sv << endl;
    }
 
private:
    std::string id_;
};
 
using ObjectPtr = std::shared_ptr<Object>;
 
struct ObjectFactory {
    ObjectPtr operator()(std::string id) const {
        return std::make_shared<Object>(std::move(id));
    }
};
 
void Test1() {
    using namespace std;
    ObjectPtr alice1;
    // Кэш, объектов Object, создаваемых при помощи ObjectFactory,
    // доступ к которым предоставляется по ключу типа string
    Cache<string, Object, ObjectFactory> cache;
 
    // Извлекаем объекты Alice и Bob
    alice1 = cache.GetValue("Alice"s);
    auto bob = cache.GetValue("Bob"s);
    // Должны вернуться два разных объекта с правильными id
    assert(alice1 != bob);
    assert(alice1->GetId() == "Alice"s);
    assert(bob->GetId() == "Bob"s);
 
    // Повторный запрос объекта Alice должен вернуть существующий объект
    auto alice2 = cache.GetValue("Alice"s);
    assert(alice1 == alice2);
 
    // Указатель alice_wp следит за жизнью объекта Alice
    weak_ptr alice_wp{alice1};
    alice1.reset();
    assert(!alice_wp.expired());
    cout << "---"sv << endl;
    alice2.reset();
    // Объект Alice будет удалён, так как на него больше не ссылаются shared_ptr
    assert(alice_wp.expired());
    cout << "---"sv << endl;
    // Объект Bob будет удалён, после разрушения указателя bob
 
    alice1 = cache.GetValue("Alice"s);  // объект 'Alice' будет создан заново
    cout << "---"sv << endl;
}
 
struct Book {
    Book(std::string title, std::string content)
        : title(std::move(title))
        , content(std::move(content)) {
    }
 
    std::string title;
    std::string content;
};
 
// Функциональный объект, загружающий книги из unordered_map
class BookLoader {
public:
    using BookStore = std::unordered_map<std::string, std::string>;
 
    // Принимает константную ссылку на хранилище книг и ссылку на переменную-счётчик загрузок
    explicit BookLoader(const BookStore& store, size_t& load_count) {
        // Реализуйте конструктор самостоятельно
    }
 
    // Загружает книгу из хранилища по её названию и возвращает указатель
    // В случае успешной загрузки (книга есть в хранилище)
    // нужно увеличить значения счётчика загрузок load_count, переданного в конструктор, на 1.
    // Если книга в хранилище отсутствует, нужно выбросить исключение std::out_of_range,
    // а счётчик не увеличивать
    std::shared_ptr<Book> operator()(const std::string& title) const {
        // Заглушка, реализуйте метод самостоятельно
        (void) title;
        throw std::out_of_range("Not implemented"s);
    }
 
private:
    // Добавьте необходимые данные и/или методы
};
 
void Test2() {
    using namespace std;
    // Хранилище книг.
    BookLoader::BookStore books{
        {"Sherlock Holmes"s,
         "To Sherlock Holmes she is always the woman. I have seldom heard him mention her under any other name."s},
        {"Harry Potter"s, "Chapter 1. The boy who lived. ...."s},
    };
    using BookCache = Cache<string, Book, BookLoader>;
 
    size_t load_count = 0;
    // Создаём кэш, который будет использщовать BookLoader для загрузки книг из хранилища books
    BookCache book_cache{BookLoader{books, load_count}};
 
    // Загруженная книга должна содержать данные из хранилища
    auto book1 = book_cache.GetValue("Sherlock Holmes"s);
    assert(book1);
    assert(book1->title == "Sherlock Holmes"s);
    assert(book1->content == books.at(book1->title));
    assert(load_count == 1);
 
    // Повторный запрос книги должен возвращать закешированное значение
    auto book2 = book_cache.GetValue("Sherlock Holmes"s);
    assert(book2);
    assert(book1 == book2);
    assert(load_count == 1);
 
    weak_ptr<Book> weak_book{book1};
    assert(!weak_book.expired());
    book1.reset();
    book2.reset();
    // Книга удаляется, как только на неё перестают ссылаться указатели вне кэша
    assert(weak_book.expired());
 
    book1 = book_cache.GetValue("Sherlock Holmes"s);
    assert(load_count == 2);
    assert(book1);
 
    try {
        book_cache.GetValue("Fifty Shades of Grey"s);
        // BookLoader выбросит исключение при попытке загрузить несуществующую книгу
        assert(false);
    } catch (const std::out_of_range&) {
        /* Всё нормально. Такой книги нет в книгохранилище */
    } catch (...) {
        cout << "Unexpected exception"sv << endl;
    }
    // Счётчик загрузок не должен обновиться, так как книги нет в хранилище
    assert(load_count == 2);
 
    // Добавляем книгу в хранилище
    books["Fifty Shades of Grey"s] = "I scowl with frustration at myself in the mirror..."s;
 
    try {
        auto book = book_cache.GetValue("Fifty Shades of Grey"s);
        // Теперь книга должна быть успешно найдена
        assert(book->content == books.at("Fifty Shades of Grey"s));
    } catch (...) {
        assert(false);
    }
    // Счётчик загрузок должен обновиться, так как книги есть в хранилище
    assert(load_count == 3);
}
 
int main() {
    Test1();
    Test2();
}
0
IT_Exp
Эксперт
34794 / 4073 / 2104
Регистрация: 17.06.2006
Сообщений: 32,602
Блог
12.07.2022, 02:35
Ответы с готовыми решениями:

Умный указатель
Здраствуйте. Есть такое задание Тема: «Работа с указателями. Указатели на функцию.» Цель: создать свой собственный ”умный...

Умный указатель
Не могу понять тему с перегрузкой оператора селектор и найти понятное объяснение этой темы. А так же реализацию умного указателя. ...

Умный указатель
Хочу передать умный указатель в конструктор объекта (может быть nullptr), но как это сделать лучше (ссылку или значение)?

0
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
BasicMan
Эксперт
29316 / 5623 / 2384
Регистрация: 17.02.2009
Сообщений: 30,364
Блог
12.07.2022, 02:35
Помогаю со студенческими работами здесь

Декоратор и умный указатель
пускай у нас есть, например, декоратор - для примера возьмем реализацию с википедии, через shared_ptr. #include &lt;iostream&gt; ...

Умный указатель своими руками
Доброго времени суток. Изобразил следующую структуру: имеется класс-контейнер, фактически обертка для одномерного массива. И...

умный указатель std::unique_ptr
Добрый день. Как происходит разыменование умного указателя std::unique_ptr? Например. void...

Умный указатель для класа
Нужно написать клас умный указатель для матрицы чтобы в результате с помощью этого указателя можно было перемещаться по матрице и...

Функция, возвращающая умный указатель
Здравствуйте, помогите пожалуйста создать функцию, возвращающую умный указатель. Мой вариант не рабочий: class InterfaceVideo{ public:...


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

Или воспользуйтесь поиском по форуму:
1
Ответ Создать тему
Новые блоги и статьи
PhpStorm 2025.3: WSL Terminal всегда стартует в ~
and_y87 14.12.2025
PhpStorm 2025. 3: WSL Terminal всегда стартует в ~ (home), игнорируя директорию проекта Симптом: После обновления до PhpStorm 2025. 3 встроенный терминал WSL открывается в домашней директории. . .
Access
VikBal 11.12.2025
Помогите пожалуйста !! Как объединить 2 одинаковые БД Access с разными данными.
Новый ноутбук
volvo 07.12.2025
Всем привет. По скидке в "черную пятницу" взял себе новый ноутбук Lenovo ThinkBook 16 G7 на Амазоне: Ryzen 5 7533HS 64 Gb DDR5 1Tb NVMe 16" Full HD Display Win11 Pro
Музыка, написанная Искусственным Интеллектом
volvo 04.12.2025
Всем привет. Некоторое время назад меня заинтересовало, что уже умеет ИИ в плане написания музыки для песен, и, собственно, исполнения этих самых песен. Стихов у нас много, уже вышли 4 книги, еще 3. . .
От async/await к виртуальным потокам в Python
IndentationError 23.11.2025
Армин Ронахер поставил под сомнение async/ await. Создатель Flask заявляет: цветные функции - провал, виртуальные потоки - решение. Не threading-динозавры, а новое поколение лёгких потоков. Откат?. . .
Поиск "дружественных имён" СОМ портов
Argus19 22.11.2025
Поиск "дружественных имён" СОМ портов На странице: https:/ / norseev. ru/ 2018/ 01/ 04/ comportlist_windows/ нашёл схожую тему. Там приведён код на С++, который показывает только имена СОМ портов, типа,. . .
Сколько Государство потратило денег на меня, обеспечивая инсулином.
Programma_Boinc 20.11.2025
Сколько Государство потратило денег на меня, обеспечивая инсулином. Вот решила сделать интересный приблизительный подсчет, сколько государство потратило на меня денег на покупку инсулинов. . . .
Ломающие изменения в C#.NStar Alpha
Etyuhibosecyu 20.11.2025
Уже можно не только тестировать, но и пользоваться C#. NStar - писать оконные приложения, содержащие надписи, кнопки, текстовые поля и даже изображения, например, моя игра "Три в ряд" написана на этом. . .
Мысли в слух
kumehtar 18.11.2025
Кстати, совсем недавно имел разговор на тему медитаций с людьми. И обнаружил, что они вообще не понимают что такое медитация и зачем она нужна. Самые базовые вещи. Для них это - когда просто люди. . .
Создание Single Page Application на фреймах
krapotkin 16.11.2025
Статья исключительно для начинающих. Подходы оригинальностью не блещут. В век Веб все очень привыкли к дизайну Single-Page-Application . Быстренько разберем подход "на фреймах". Мы делаем одну. . .
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2025, CyberForum.ru