#c #unit-testing #c 11 #googletest #scoped-ptr
#c #модульное тестирование #c 11 #googletest #scoped-ptr
Вопрос:
Предположим, я реализовал scoped_ptr
:
template <typename T> class scoped_ptr {
public:
scoped_ptr() = delete;
explicit scoped_ptr(T *ptr) : _ptr(ptr){};
~scoped_ptr() {
delete _ptr;
_ptr = nullptr;
};
scoped_ptr(const scoped_ptr amp;p) = delete;
scoped_ptr amp;operator=(const scoped_ptr amp;p) = delete;
T *operator->() const { return _ptr; }
T amp;operator*() const { return *_ptr; }
T *get() const { return _ptr; }
void reset(T *p = nullptr) {
delete _ptr;
_ptr = p;
}
private:
T *_ptr;
};
Я хочу проверить, что память действительно освобождается после истечения срока службы указателя, но я не могу проверить это путем разыменования этого необработанного указателя _ptr
, потому что ожидается, что память, на которую он указывает, должна была уже быть освобождена. Тогда как мне это протестировать?
Комментарии:
1. Вы можете протестировать его с помощью специально разработанного класса, который выполняет что-то проверяемое в своем деструкторе и / или
operator delete
Ответ №1:
Как насчет использования класса с количеством объектов? Примечание: вам необходимо проверить самоназначение reset
.
Демонстрация: https://ideone.com/hnxc9o .
#include <cassert>
#include <iostream>
using namespace std;
template <typename T>
class scoped_ptr {
public:
scoped_ptr() = delete;
explicit scoped_ptr(T *ptr) : _ptr(ptr) {}
virtual ~scoped_ptr() { reset(); }
scoped_ptr(const scoped_ptr amp;p) = delete;
scoped_ptr amp;operator=(const scoped_ptr amp;p) = delete;
T* operator->() const { return _ptr; }
Tamp; operator*() const { return *_ptr; }
T* get() const { return _ptr; }
void reset(T* p = nullptr) {
if (_ptr == p) {
return;
}
delete _ptr;
_ptr = p;
}
private:
T* _ptr;
};
struct ObjectCounter {
static int _object_count;
ObjectCounter() {
_object_count;
}
virtual ~ObjectCounter() {
--_object_count;
}
};
int ObjectCounter::_object_count = 0;
int main() {
{
scoped_ptr<ObjectCounter> ptr(new ObjectCounter());
assert(ObjectCounter::_object_count == 1);
}
assert(ObjectCounter::_object_count == 0);
return 0;
}