Задача поставлена следующим образом: создать класс умный указатель, с которым можно будет реализовать следующее:
int main()
{
SmartPointer <int> p1 = new int(2);
p1->Method1();
p1[2] = int(); // должна быть ошибка на этапе компиляции
SmartPointer <int[]> p2 = new int[3];
p2->Method1(); //должна быть ошибка на этапе компиляции
p2[2] = int();
return 0;
}
если создаем объект Object = new Object(3);
- тогда мы можем обратиться с помощью стрелки ко всем методам которыми обладает объект Object
если мы создали массив объект Object = new Object[3]
- тогда мы не можем обратиться с помощью стрелки к массиву.
Код ниже:
template <typename T>
class SmartPointer
{
private:
DefaultDeleter<T> m_deleter;
Counter *m_count = nullptr;
T *m_ptr = nullptr;
typedef std::remove_all_extents_t<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 <typename T>
class DefaultDeleter
{
public:
void Delete(T* const ptr)
{
delete ptr;
}
};
template <typename T>
class DefaultDeleter<T[]>
{
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 <int[]> p2 = new int[3];
Вам нужно просто сделать два разных класса: один для массива, другой - для скаляра. Так же это сделано для std::unique_ptr
. Пример:
template <class T>
struct smartPtr {
T* operator->() { return ptr; }
T* ptr;
};
template <class T>
struct smartPtr<T[]> {
T& operator[](int i) { return ptr[i]; }
T* ptr;
};
struct A {
void foo() {}
};
int main()
{
smartPtr<A> ip;
ip->foo();
ip[0]; // error
smartPtr<A[]> ia;
ia->foo(); // error
ia[0].foo();
}
Оборудование для ресторана: новинки профессиональной кухонной техники
Частный дом престарелых в Киеве: комфорт, забота и профессиональный уход
Как в Qt можно реализовать меню "Окно" MDI-приложения, отражающее открытые внутренние окна и позволяющее переключаться между ними? Пока приходит...
написал простенький класс который работает как однопоточный http сервер, выдающий текущее время и дату, если обратиться по 1270
Когда я записываю цифру в переменную, цифра храниться до того момента, покуда я другое значение не запишу, а мне нужно сделать, чтоб старое...
Например, в C# есть TcpClientReceiveBufferSize и TcpClient