Почему я вижу необычное поведение при использовании std :: vector с конструктором по умолчанию?

Резюме

Недавно я видел несколько вопросов по std :: vector и из любопытства играл с их немного. Я никогда особо не использовал STL, но я знал, что вы можете использовать вектор для распределения массивов объектов, и я мог бы поклясться, что есть способ использовать конструктор по умолчанию для распределения элементов внутри, когда вектор созданный. Действительно, этот вопрос Инициализация std :: vector с конструктором по умолчанию касается инициализации вектора с использованием либо конструктора копирования и значения по умолчанию, а не просто использования конструктора по умолчанию.

Однако, как я делал это раньше экспериментируя в Visual Studio 2010 с проектом консольного приложения C ++, я не получил результатов, согласующихся с этим объяснением. Согласно одному из комментариев в ответе на вышеупомянутый вопрос (, данный здесь ), если вы используете, например, std :: vector FooArray = new std :: vector (20); он должен использовать конструктор по умолчанию, и это действительно было то поведение, которое я ожидал.

Однако я написал код трассировки для отслеживания объектов по мере их создания, предполагая, что они будут созданы с помощью конструктора по умолчанию, и оказалось, что каждый объект был просто создан и впоследствии немедленно уничтожен. Наконец, после долгих поисков здесь, там и повсюду, я пошел дальше и реализовал конструктор копирования, который также распечатывал информацию. Я вижу, что если я инициализирую вектор FooClass , используя значение по умолчанию, например, new std :: vector (20, FooClass ()) , тогда я получаю ожидаемый результат: создается экземпляр FooClass () , каждый из элементов в векторе инициализируется конструктором копирования как копия этого объекта, а затем значение, используемое по умолчанию, уничтожается .

Но, если я использую new std :: vector (20) , вместо использования конструктора по умолчанию, он, кажется, делает что-то немного (для меня) странное. Двадцать раз временный объект FooClass создается с использованием конструктора по умолчанию, элемент массива создается с помощью конструктора копирования с использованием временного объекта, а затем временный объект уничтожается.

Это действительно просто не " не имеет для меня смысла; но мне интересно, возможно, я просто делал что-то не так.

Код

FooClass.h

#include 

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 
#include 

#include "FooClass.h"

//#define USE_INITIALIZER

int _tmain(int argc, _TCHAR* argv[])
{
#ifdef USE_INITIALIZER
    std::vector myFooArray =
        std::vector(5, FooClass());
#else
    std::vector myFooArray =
        std::vector(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!

Вопрос

Итак ... Я Я неправильно настроил свой класс, и это ожидаемое поведение? Возможно, это причуда реализации STL Microsoft?

Или есть какое-то другое объяснение?

Заключительное примечание

Я удалил спецификации sgi и комментарии к ним, потому что, как указал ответ Джеймса , спецификация sgi не является действительной спецификацией . См., Например, ресурсы для статьи википедии о C ++ , где приведены ссылки на рабочие проекты реальных спецификаций. Всем спасибо! :)

6
задан Community 23 May 2017 в 12:03
поделиться