如何构造对象向量(具有静态成员)

时间:2011-10-18 20:26:39

标签: c++ stl static vector constructor

我编写了以下代码来测试一个具有静态成员的对象向量。我希望输出结果为:

1 2 3 4 5
6 7 8 9 10

但实际输出是:

1 2 3 4 5
6 6 6 6 6

看起来静态成员没有按预期增加。谁能解释一下呢?

// ==== test.h =====
using namespace std;

void test();

class Record{
    static int total_number;
    int id;
public: 
    Record();
    void show() {std::cout << id << " "; }
};


// ==== test.cpp ====
#include "stdafx.h"
#include <iostream>
#include <vector>
#include "test.h"
using namespace std;

Record::Record(){
    total_number += 1;
    id = total_number;
 }

void test(){

    const int vec_length = 5;
    Record a[vec_length];

    for (unsigned int i=0; i<vec_length; i++)
        a[i].show();

    cout << endl;    

    vector<Record> vr(vec_length);
    for (unsigned int i=0; i<vr.size(); i++)
        vr[i].show();
    cout << endl;
}


// ==== main.cpp =====
#include "stdafx.h"
#include <iostream>
#include "test.h"
using namespace std;

int Record::total_number = 0;

int _tmain(int argc, _TCHAR* argv[])
{
    test();
    return 0;
}

5 个答案:

答案 0 :(得分:3)

在C ++ 98/03中,使用以下构造函数初始化矢量:

std::vector<Record> v(5, Record());

这将创建一个新对象,递增静态变量,然后生成此变量的五个副本以填充元素。总共有一个默认和五个复制结构,产生6 6 6 6 6

在C ++ 11中,构造函数是:

std::vector<Record> v(5);

这为五个元素创建空间并对它们进行值初始化,对于您的类型,这意味着为每个元素调用一次默认构造函数。总共有五个默认构造,产生6 7 8 9 10

答案 1 :(得分:2)

我猜您对Record::Record的定义如下所示

Record::Record() : id(++total_number) {}

并且您希望vector<Record>构造函数只调用该构造函数。但是,vector只执行一次并通过编译器生成的复制构造函数复制其余部分,这看起来像这样:

Record::Record(const Record &other) : id(other.id) {}

你也必须覆盖它。

答案 2 :(得分:1)

vector<Record> vr(vec_length);有多松散。我假设您期望vec_length默认构造调用,但另一个可行的实现是创建一个默认构造对象,后跟vec_length-1个副本。也就是说,您未能提供适当的复制构造函数。

答案 3 :(得分:1)

我建议(并且在没有完整代码的情况下,我假设在Record :: Record()中你做了一个++ total_number)问题就在这里

vector vr(vec_length);

使用vec_length Record's初始化std :: vector。

std :: vector要求其类型是可复制构造的,即你必须实现Record :: Record(const Record&amp;)。会发生什么:由于std :: vector没有Record(),它通过构造它来创建一个(调用Record :: Record(),它将总计数增加到6)。然后通过使用刚创建的实例调用Record :: Record(const Record&amp;)来复制剩余的vec_length-1记录。

由于您还没有提供copy-ctor,编译器为您创建了一个只复制对象的按位副本。由于vec_length对于类是静态的,所以不需要复制任何东西 - 但是由于复制器没有增加静态,所以没有任何事情发生(即简单地保留该值)。

所以这些的输出是6。

答案 4 :(得分:1)

您使用的向量构造函数的定义如下:

显式向量(size_type n,const T&amp; value = T(),const Allocator&amp; = Allocator()); 重复序列构造函数:初始化向量,其内容设置为重复值n次重复。这是link to the man page

我相信这意味着向量构造函数将运行一次默认构造函数(结果为6),然后运行复制构造函数4次(导致更多6次)。