我编写了以下代码来测试一个具有静态成员的对象向量。我希望输出结果为:
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;
}
答案 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次)。