Приведенный выше код, по сути, является правильным способом написания. Однако вместо этого вы можете использовать std::vector
, поскольку вам не придется явно управлять памятью.
Если факт, std::vector
уже определит begin()
и end()
(что заменит m_pData
в вашем коде), и вам действительно не понадобится замена m_end
, поскольку вы сами не управляете памятью.
Эквивалентом будет begin() + capacity()
, но поскольку элемент не инициализируется после end
, вам все равно не следует обращаться к ним (возможно, неопределенное поведение с языковой точки зрения).
В противном случае возможны небольшие улучшения, такие как:
- Избегайте m_ для имени переменной члена. Не очень полезно.
- Избегайте префикса p для указателя на данные.
- В списке инициализации поставьте запятую в начале строки (как вы уже сделали :) вместо конца предыдущей строки. Это позволяет добавлять, удалять, перемещать или комментировать элементы, когда это делается таким образом.
Если вы не хотите, чтобы ваш объект был перемещаемым или копируемым, предпочтительно явно указать его:
public:
ByteBuffer(const ByteBuffer &) = delete;
ByteBuffer(ByteBuffer &&) = delete;
ByteBuffer &operator=(const ByteBuffer &) = delete;
ByteBuffer &operator=(ByteBuffer &&) = delete;
В качестве альтернативы, вы также можете использовать std::unique_ptr
, и тогда вам не придется освобождать память самостоятельно. Это может быть полезно, когда вашему классу нужно сделать несколько выделений или когда после выделения в конструкторе может возникнуть исключение.
Лучшее решение действительно зависит от того, что вы хотите сделать с вашим классом ByteBuffer
или даже от того, действительно ли вам нужен такой класс (как вы могли бы вместо этого использовать std::vector
напрямую или сделать простой псевдоним, такой как:
using ByteBuffer = std::vector<unsigned char>;
Если это так, byte typedef
может быть не очень полезным, если вы используете auto
для своих циклов и итераторов.
Говоря о const
, я бы порекомендовал использовать его для предотвращения нежелательных изменений. Однако иногда вам нужно сбросить эти указатели на nullptr
во время уничтожения довольно сложных классов, где может быть некоторое взаимное уничтожение, например.
Таким образом, имея простые классы, которые уважают SRP (принцип единой ответственности), вы по существу избегаете подобных проблем.