Резюме
Я недавно видел несколько вопросов о std :: vector, и из любопытства я немного поиграл с ними.Я никогда особо не использовал STL, но я знал, что вы можете использовать вектор, чтобы иметь дело с распределением массивов объектов, и я мог бы поклясться, что был способ использовать конструктор по умолчанию для выделения элементов внутри, когда векторсоздано.Действительно, этот вопрос Инициализация std :: vector конструктором по умолчанию касается инициализации вектора с использованием конструктора копирования и значения по умолчанию, а не только использования конструктора по умолчанию.
Однако, как яЯ проводил эксперименты в Visual Studio 2010 с проектом консольного приложения C ++, но я не получил результатов, согласующихся с этим объяснением.Согласно одному из комментариев в ответе на вышеупомянутый вопрос (, приведенный здесь ), если вы используете, например, std::vector<FooClass> FooArray = new std::vector<FooClass>(20);
, он должен использовать конструктор по умолчанию, и это действительно было поведение, которое я ожидал.
Однако я написал некоторый код трассировки для отслеживания объектов по мере их создания, предполагая, что они будут созданы с помощью конструктора по умолчанию, и оказалось, что каждый объект был просто создан и впоследствии немедленно уничтожен.Наконец, после долгих поисков здесь, там и везде, я пошел дальше и реализовал конструктор копирования, который также распечатывал информацию.Я вижу, что если я инициализирую вектор FooClass
, используя значение по умолчанию, например, new std::vector<FooClass>(20, FooClass())
, то получу ожидаемый результат: создается экземпляр FooClass()
, каждый из элементов в вектореинициализируется с помощью конструктора копирования как копии этого объекта, а затем значение, используемое в качестве значения по умолчанию, уничтожается.
Но, если я сделаю new std::vector<FooClass>(20)
, вместо использования конструктора по умолчанию, это, кажется, делаетчто-то немного странное (для меня).Двадцать раз временный объект FooClass
создается с помощью конструктора по умолчанию, элемент массива создается с помощью конструктора копирования с использованием временного, а затем временный уничтожается.
Это действительно просто неимеет смысл для меня;но мне интересно, возможно, я просто делал что-то не так.
Код
FooClass.h
#include <stdio.h>
class FooClass
{
public:
FooClass()
{
printf("Foo %i Created!\n", NumFoos);
myFooNumber = FooClass::NumFoos;
++FooClass::NumFoos;
myIsACopy = false;
}
FooClass(const FooClass& Another)
{
printf("Foo %i (a copy of Foo %i) Created!\n", FooClass::NumFoos, Another.myFooNumber);
myFooCopiedFrom = Another.myFooNumber;
myFooNumber = FooClass::NumFoos;
++FooClass::NumFoos;
myIsACopy = true;
}
void PrintMe()
{
if (myIsACopy)
printf("I'm Foo %i (a copy of Foo %i)!\n", myFooNumber, myFooCopiedFrom);
else
printf("I'm Foo %i!\n", myFooNumber);
}
~FooClass()
{
printf("Foo %i Deleted!\n", myFooNumber);
}
private:
int myFooCopiedFrom;
int myFooNumber;
bool myIsACopy;
private:
static int NumFoos;
};
FooClass.cpp
#include "FooClass.h"
int FooClass::NumFoos = 0;
FooVector.cpp
// FooVector.cpp : Defines the entry point for the console application.
#include "stdafx.h"
#include <memory>
#include <vector>
#include "FooClass.h"
//#define USE_INITIALIZER
int _tmain(int argc, _TCHAR* argv[])
{
#ifdef USE_INITIALIZER
std::vector<FooClass> myFooArray =
std::vector<FooClass>(5, FooClass());
#else
std::vector<FooClass> myFooArray =
std::vector<FooClass>(5);
#endif
for (int i=0; i < 5; ++i)
myFooArray[i].PrintMe();
printf("We're done!\n");
return 0;
}
Вывод с инициализатором по умолчанию
Foo 0 Created!
Foo 1 (a copy of Foo 0) Created!
Foo 2 (a copy of Foo 0) Created!
Foo 3 (a copy of Foo 0) Created!
Foo 4 (a copy of Foo 0) Created!
Foo 5 (a copy of Foo 0) Created!
Foo 0 Deleted!
I'm Foo 1 (a copy of Foo 0)!
I'm Foo 2 (a copy of Foo 0)!
I'm Foo 3 (a copy of Foo 0)!
I'm Foo 4 (a copy of Foo 0)!
I'm Foo 5 (a copy of Foo 0)!
We're done!
Вывод без инициализатора
Foo 0 Created!
Foo 1 (a copy of Foo 0) Created!
Foo 0 Deleted!
Foo 2 Created!
Foo 3 (a copy of Foo 2) Created!
Foo 2 Deleted!
Foo 4 Created!
Foo 5 (a copy of Foo 4) Created!
Foo 4 Deleted!
Foo 6 Created!
Foo 7 (a copy of Foo 6) Created!
Foo 6 Deleted!
Foo 8 Created!
Foo 9 (a copy of Foo 8) Created!
Foo 8 Deleted!
I'm Foo 1 (a copy of Foo 0)!
I'm Foo 3 (a copy of Foo 2)!
I'm Foo 5 (a copy of Foo 4)!
I'm Foo 7 (a copy of Foo 6)!
I'm Foo 9 (a copy of Foo 8)!
We're done!
Вопрос
Итак ... Я неправильно настраиваю свой класс, и это ожидаемоеповедение?Это, возможно, причуды реализации Microsoft STL?
Или есть какое-то другое объяснение целиком?
Заключительное примечание
Я удалил спецификации sgi и комментарии к ним, потому что, как указал ответ Джеймса спецификация sgi не является действительной спецификацией.См., Например, ресурсы для записи в Википедии на C ++ для ссылок на рабочие проекты реальных спецификаций.Спасибо всем!:)