буфер char * в реализации Vector - PullRequest
0 голосов
/ 13 апреля 2020

Я просматривал реализации векторного / обобщенного управления памятью. Я нашел вопрос о просмотре кода и не понимаю, как работает одно из предложений.

Вот фрагмент соответствующей части вопроса (код):

template <class T>
class  Vector {
public:

    typedef T* Iterator;

    Vector();
    Vector(unsigned int size);
    Vector(unsigned int size, const T & initial);
    Vector(const Vector<T>& v);
    ~Vector();

    unsigned int capacity() const;
    unsigned int size() const;
    bool empty() const;
    Iterator begin();
    Iterator end();
    T& front();
    T& back();
    void push_back(const T& value);
    void pop_back();

    void reserve(unsigned int capacity);
    void resize(unsigned int size);

    T & operator[](unsigned int index);
    Vector<T> & operator = (const Vector<T> &);
    void clear();
private:
    unsigned int _size;
    unsigned int _capacity;
    unsigned int Log;
    T* buffer;
};

В отношении этого ответа, почему он рекомендует использовать буфер char* вместо T*, и, что более важно, как это работает и что это значит ? Я понимаю, что указатель char не имеет инициализации, но я думаю, что вы могли бы только использовать T* ... как тип generi c вписывается в указатель char?

Соответствующая часть ответа:

Вам будет трудно выполнить эту работу, если буфер имеет тип T. Каждый раз, когда вы расширяете буфер, все элементы в буфере будут инициализироваться с конструктором Т. Для int это не проблема. Но если у T нетривиальный конструктор, то вы заплатите высокую цену за инициализирующие элементы, которые никогда не могут быть использованы.

T* buffer;

На самом деле буфер должен быть чем-то, что не имеет конструктора.

char* buffer;

1 Ответ

2 голосов
/ 13 апреля 2020

Объяснение прямо в ответе ,

Вам будет трудно сделать эту работу, если буфер имеет тип T. Каждый раз, когда вы расширяете буфер, все элементы в буфере будут инициализироваться конструктором T. Для int это не проблема. Но если T имеет нетривиальный конструктор, то вы заплатите высокую цену за инициализирующие элементы, которые никогда не могут быть использованы.

Когда вы можете использовать

char* buffer_;

all неиспользуемые элементы buffer_ будут содержать неинициализированные данные, но это нормально. Вы не платите цену инициализации каждого объекта с помощью нетривиального конструктора, которую вы должны заплатить, когда вы используете

T* buffer_;

@ FrancoisAndrieux. Если T не является конструируемым по умолчанию, вы не сможете использовать new T[capacity] для выделения памяти.

Что касается вашего комментария, для хранения любого объекта может использоваться массив из char объектов. Вам просто нужно выделить соответствующее количество char объектов. Вместо capacity количества T объектов вам нужно выделить capacity*sizeof(T) количество char объектов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...