#cpp #шаблоны_с++
Задача поставлена следующим образом: создать класс умный указатель, с которым можно будет реализовать следующее: int main() { SmartPointerp1 = new int(2); p1->Method1(); p1[2] = int(); // должна быть ошибка на этапе компиляции SmartPointer p2 = new int[3]; p2->Method1(); //должна быть ошибка на этапе компиляции p2[2] = int(); return 0; } если создаем объект Object = new Object(3); - тогда мы можем обратиться с помощью стрелки ко всем методам которыми обладает объект Object если мы создали массив объект Object = new Object[3] - тогда мы не можем обратиться с помощью стрелки к массиву. Код ниже: template class SmartPointer { private: DefaultDeleter m_deleter; Counter *m_count = nullptr; T *m_ptr = nullptr; typedef std::remove_all_extents_t ptr; public: SmartPointer(T* const ptr) : m_count(new Counter), m_ptr(ptr) { m_count->incrementCount(); } SmartPointer(const SmartPointer &source) m_count(source.m_count), m_ptr(source.m_ptr) { m_count->incrementCount(); } SmartPointer& operator=(const SmartPointer &right) { m_count->decrementCount(); return SmartPointer(right).Swap(*this); } T& operator*() { return *m_ptr; } T* operator->() { return m_ptr; } T& operator[](unsigned int index) { return m_ptr[index]; } SmartPointer& Swap(SmartPointer& other) { std::swap(m_ptr, other.m_ptr); return *this; } ~SmartPointer() { { m_count->decrementCount(); if (m_count->getCount() == 0) { m_deleter.Delete(m_ptr); delete m_count; } } } }; template class DefaultDeleter { public: void Delete(T* const ptr) { delete ptr; } }; template class DefaultDeleter { public: void Delete(T* const ptr) { delete[] ptr; } }; class Counter { private: unsigned int m_uses=0; public: void incrementCount() { ++m_uses; } void decrementCount() { --m_uses; } unsigned int getCount() { return m_uses; } }; Не совсем понятно как сделать так что бы компилятор понимал где (), а где [] где один элемент, а где массив элементов + как исправить ошибку в этой строке кода: SmartPointer p2 = new int[3];
Ответы
Ответ 1
Вам нужно просто сделать два разных класса: один для массива, другой - для скаляра. Так же это сделано для std::unique_ptr. Пример: templatestruct smartPtr { T* operator->() { return ptr; } T* ptr; }; template struct smartPtr { T& operator[](int i) { return ptr[i]; } T* ptr; }; struct A { void foo() {} }; int main() { smartPtr ip; ip->foo(); ip[0]; // error smartPtr ia; ia->foo(); // error ia[0].foo(); }
Комментариев нет:
Отправить комментарий