Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <algorithm>
- #include <cassert>
- #include <vector>
- #include <stdexcept>
- #include <exception>
- #include <iostream>
- using namespace std;
- template <typename T>
- class PtrVector {
- public:
- PtrVector() = default;
- // Создаёт вектор указателей на копии объектов из other
- PtrVector(const PtrVector& other) {
- // Реализуйте копирующий конструктор самостоятельно
- items_.reserve(other.GetItems().size());
- for (auto item : other.GetItems()) {
- if (item != nullptr) {
- T* item_copy = new T(*item);
- items_.push_back(item_copy);
- } else {
- items_.push_back(nullptr);
- }
- }
- }
- // Деструктор удаляет объекты в куче, на которые ссылаются указатели,
- // в векторе items_
- ~PtrVector() {
- // Реализуйте тело деструктора самостоятельно
- for (auto item : items_) {
- delete item;
- }
- }
- // Возвращает ссылку на вектор указателей
- vector<T*>& GetItems() noexcept {
- // Реализуйте метод самостоятельно
- return items_;
- }
- // Возвращает константную ссылку на вектор указателей
- vector<T*> const& GetItems() const noexcept {
- // Реализуйте метод самостоятельно
- return items_;
- }
- private:
- vector<T*> items_;
- };
- // Эта функция main тестирует шаблон класса PtrVector
- int main() {
- // Вспомогательный "шпион", позволяющий узнать о своём удалении
- struct DeletionSpy {
- explicit DeletionSpy(bool& is_deleted)
- : is_deleted_(is_deleted) {
- }
- ~DeletionSpy() {
- is_deleted_ = true;
- }
- bool& is_deleted_;
- };
- // Проверяем удаление элементов
- {
- bool spy1_is_deleted = false;
- DeletionSpy* ptr1 = new DeletionSpy(spy1_is_deleted);
- {
- PtrVector<DeletionSpy> ptr_vector;
- ptr_vector.GetItems().push_back(ptr1);
- assert(!spy1_is_deleted);
- // Константная ссылка на ptr_vector
- const auto& const_ptr_vector_ref(ptr_vector);
- // И константная, и неконстантная версия GetItems
- // должны вернуть ссылку на один и тот же вектор
- assert(&const_ptr_vector_ref.GetItems() == &ptr_vector.GetItems());
- }
- // При разрушении ptr_vector должен удалить все объекты, на которые
- // ссылаются находящиеся внутри него указателели
- assert(spy1_is_deleted);
- }
- // Вспомогательный «шпион», позволяющий узнать о своём копировании
- struct CopyingSpy {
- explicit CopyingSpy(int& copy_count)
- : copy_count_(copy_count) {
- }
- CopyingSpy(const CopyingSpy& rhs)
- : copy_count_(rhs.copy_count_) //
- {
- ++copy_count_;
- }
- int& copy_count_;
- };
- // Проверяем копирование элементов при копировании массива указателей
- {
- // 10 элементов
- vector<int> copy_counters(10);
- PtrVector<CopyingSpy> ptr_vector;
- // Подготавливаем оригинальный массив указателей
- for (auto& counter : copy_counters) {
- ptr_vector.GetItems().push_back(new CopyingSpy(counter));
- }
- // Последний элемент содержит нулевой указатель
- ptr_vector.GetItems().push_back(nullptr);
- auto ptr_vector_copy(ptr_vector);
- // Количество элементов в копии равно количеству элементов оригинального вектора
- assert(ptr_vector_copy.GetItems().size() == ptr_vector.GetItems().size());
- // копия должна хранить указатели на новые объекты
- assert(ptr_vector_copy.GetItems() != ptr_vector.GetItems());
- // Последний элемент исходного массива и его копии - нулевой указатель
- assert(ptr_vector_copy.GetItems().back() == nullptr);
- // Проверяем, что элементы были скопированы (копирующие шпионы увеличивают счётчики копий).
- assert(all_of(copy_counters.begin(), copy_counters.end(), [](int counter) {
- return counter == 1;
- }));
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement