Распределение векторов STL - PullRequest
3 голосов
/ 17 июня 2009

Мне было интересно, почему векторные шаблоны выполняют два выделения, когда кажется, что только один необходимо.

Например, это:

#include <vector>
#include <iostream>

class A {
    public:
         A(const A &a) {
            std::cout << "Calling copy constructor " << this << " " << &a << "\n";
        }
         A() {
            std::cout << "Calling default constructor " << this << "\n";
        }
        ~A() {
            std::cout << "Calling destructor " << this << "\n"; 
        }
};

int main(int argc, char **argv)
{
    std::vector <A> Avec;

    std::cout << "resize start\n";
    Avec.resize(1);
    std::cout << "resize end\n";

    return 0;
}

Выходы:

resize start
Calling default constructor 0x7fff9a34191f
Calling copy constructor 0x1569010 0x7fff9a34191f
Calling destructor 0x7fff9a34191f
resize end

Ответы [ 3 ]

15 голосов
/ 17 июня 2009

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

Если вы посмотрите на аргументы для изменения размера:

void resize(n, t = T())

Он имеет в качестве аргумента по умолчанию сконструированный объект по умолчанию типа T (это конструктор по умолчанию, вызываемый в ваших выходных данных). Затем, внутри функции, он копирует это в правильную позицию (это конструктор копирования). После завершения функции изменения размера уничтожает аргумент (вызов деструктора в выводе).

0 голосов
/ 17 июня 2009

Вот предположение:

  1. Компилятор переупорядочил начальное распределение Avec до тех пор, пока не начнется "изменение размера"
  2. Вектор изначально выделен 0 элементами
  3. При изменении размера новый элемент заполняется значением по умолчанию A (что было достигнуто путем создания значения по умолчанию A, копирования его в вектор и удаления временного элемента.
0 голосов
/ 17 июня 2009

Если вы инициализируете объекты таким образом, векторный шаблон создает объекты путем создания копии. Если вы не хотите вызывать конструктор копирования, вы должны сделать:

vector<A*> Avec;
avec.push_back(new A());

http://www.cplusplus.com/reference/stl/vector/vector/

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