Фон
Я работаю с криптографическими библиотеками Intel IPP для тестирования.
Они определяют несколько непрозрачных структур, используемых для общих контекстов над такими вещами, как хеширование и шифрование, которые, конечно, не могут быть непосредственно созданы.
Чтобы инициализировать одну из этих непрозрачных структур, вы запрашиваете размер байта, а затем динамически выделяете несколько байтов и приводите к указателю структуры.
Их примеры работают примерно так:
int byteSize = 0;
ippsSHA256GetSize(&byteSize);
// IppsSHA256State shaCtx; // Error: incomplete type is not allowed
IppsSHA256State * shaCtx = (IppsSHA256State *)(new uint8_t[byteSize]);
// use shaCtx
delete [] (uint8_t *)shaCtx;
Вопрос
Как правильно обернуть это в класс указателя с областью видимости, чтобы мне не пришлось беспокоиться об освобождении?
Вещи, которые я пробовал
Я думаю, что следующее не будет безопасным, поскольку вызов delete в деструкторе будет иметь тип T, а не delete [] в массиве, который был на самом деле Распределить:
boost::scoped_ptr<IppsSHA256State> ctx(
reinterpret_cast<IppsSHA256State *>(new uint8_t[byteSize])
);
Другой (упрощенный) вариант, который я рассмотрел, - это мой собственный класс указателей с областью видимости, но приведение к нему заставляет меня сомневаться в правильности этого, хотя мое понимание reinterpret_cast таково, что при приведении назад к исходному типу не должно быть никакой двусмысленности:
template <typename T>
class IppsScopedState
{
public:
explicit IppsScopedState(size_t byteSize)
: _ptr(reinterpret_cast<T *>(new uint8_t[byteSize]))
{}
T * get() const { return _ptr; }
~IppsScopedState(void) {
if (_ptr) delete [] reinterpret_cast<uint8_t *>(_ptr);
}
private:
T * _ptr;
//NUKE_COPYASSIGN_CONSTRUCTORS
};
Наконец, я рассмотрел небольшое отклонение от вышесказанного:
template <typename T>
class IppsScopedState
{
public:
explicit IppsScopedState(size_t byteSize)
: _ptr(new uint8_t[byteSize])
{}
T * get() const { return reinterpret_cast<T *>(_ptr); }
~IppsScopedState(void) {
if (_ptr) delete [] _ptr;
}
private:
uint8_t * _ptr;
//NUKE_COPYASSIGN_CONSTRUCTORS
};
В любом случае использование будет таким:
IppsScopedState<IppsSHA256State> ctx(byteSize); // after querying for the byteSize, of course