c – 为什么在使用带有默认构造函数的std :: vector时会看到异常行为?

前端之家收集整理的这篇文章主要介绍了c – 为什么在使用带有默认构造函数的std :: vector时会看到异常行为?前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
摘要

我最近在std :: vector上看到了一些问题,出于好奇,我一直在玩它们.我从来没有真正使用STL,但我知道你可以使用vector来处理对象数组的分配,我可以发誓有一种方法可以使用默认构造函数在向量中分配项目.创建.实际上,这个问题Initializing a std::vector with default constructor涉及使用复制构造函数和默认值而不是使用默认构造函数初始化向量.

但是,由于我一直在使用C控制台应用程序项目在Visual Studio 2010中进行一些实验,因此我没有得到与此解释一致的结果.根据上述问题(given here)的答案中的一个评论,如果你使用,例如,std :: vector< FooClass> FooArray = new std :: vector< FooClass>(20);它应该使用默认构造函数,这确实是我期望的行为.

但是我编写了一些跟踪代码来跟踪对象的创建,假设它们是使用默认构造函数创建的,并且看起来每个对象都是刚创建的,随后立即被销毁.最后经过多次搜索,在那里,到处都是,我继续实施了一个复制构造函数,也打印出了信息.我所看到的是,如果我使用默认值初始化FooClass的向量,使用新的std :: vector< FooClass>(20,FooClass()),那么我得到预期的结果:FooClass()是实例化后,向量中的每个项都使用复制构造函数初始化为该对象的副本,然后销毁用作默认值的值.

但是,如果我做新的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!

问题

所以……我是不正确地设置我的课程,这是预期的行为?这可能是微软实施STL的一个怪癖吗?

还是完全有其他解释?

最后的说明

删除了sgi规范和评论,因为正如James’s answer所指出的那样,sgi规范不是实际的规范.例如,请参阅wikipedia’s entry on C++的资源,以获取实际规格工作草案的链接.感谢大家!

猜你在找的C&C++相关文章