如何构造对象向量(具有静态成员)
我编写了以下代码来测试具有静态成员的对象向量。我预计输出将是:
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;
}
I wrote the following code to test a vector of objects, which have a static member. I expect the output would be:
1 2 3 4 5
6 7 8 9 10
But the actual output is:
1 2 3 4 5
6 6 6 6 6
It looks like the static member is not incremented as expected. Can anyone explain this?
// ==== 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;
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
在 C++98/03 中,您的向量使用此构造函数进行初始化:
这将创建一个新对象,递增静态变量,然后创建此变量的五个副本以填充元素。总共有 1 个默认构造函数和 5 个复制构造函数,生成
6 6 6 6 6
在 C++11 中,构造函数为:
这为 5 个元素创建了空间并对它们进行了值初始化,这对于您的type 意味着每个元素都会调用一次默认构造函数。总共有五个默认结构,产生
6 7 8 9 10
。In C++98/03, your vector is initialized with this constructor:
This creates one new object, incrementing the static variable, and then makes five copies of this variable to populate the elements. In total, one default- and five copy-constructions, yielding
6 6 6 6 6
In C++11, the constructor is:
This creates space for five elements and value-initializes them, which for your type means that the default constructor is called once for each element. In total, five default-constructions, yielding
6 7 8 9 10
.我猜您对
Record::Record
的定义如下所示,并且您希望
vector
构造函数仅调用该构造函数。然而,向量只执行一次,并通过编译器生成的复制构造函数复制其余部分,这看起来像这样:您也必须覆盖它。
I guess your definition of
Record::Record
looks like thisand you expect the
vector<Record>
constructor to call just that constructor. However, vector only does that once and copies the rest via the compiler generated copy constructor, which would look something like this:You will have to overwrite that too.
向量如何创建vr(vec_length);
有点松散。我假设您期望vec_length
默认构造调用,但另一种可行的实现是创建一个默认构造对象,然后创建vec_length-1
副本。也就是说,您未能提供适当的复制构造函数。How a
vector<Record> vr(vec_length);
is somewhat loose. I assume you would be expectingvec_length
default construction calls, but another viable implementation is to create one default constructed object followed byvec_length-1
copies. That said, you failed to provide an appropiate copy-constructor.我建议(在没有完整代码的情况下,我假设在 Record::Record() 中你做了一个 ++total_number ),问题出在此处
向量 vr(vec_length);
它用 vec_length 记录初始化 std::vector 。
std::vector 要求其类型是可复制构造的,即您必须实现 Record::Record(const Record&)。发生的情况是这样的:由于 std::vector 没有 Record(),因此它通过构造它来创建一个(调用 Record::Record(),这会将总计数增加到 6)。然后通过使用刚刚创建的实例调用 Record::Record(const Record&) 来复制剩余的 vec_length-1 记录。
由于您没有提供复制因子,编译器已为您创建了一个复制因子,它只是对对象进行按位复制。由于 vec_length 对于类来说是静态的,因此不需要复制任何内容 - 但也因为复制因子不会增加静态,因此不会发生任何事情(即,该值只是被保留)。
所以这些的输出是 6。
I'd suggest (and in the absence of the full code I assume that in Record::Record() you do an ++total_number) that the problem is here
vector vr(vec_length);
which initializes std::vector with vec_length Record's.
std::vector requires its types to be copy-constructible, i.e. you would have to implement Record::Record(const Record&). What happens is this: since std::vector has no Record(), it creates one by constructing it (Record::Record() is called, which increments total count to 6). Then the remaining vec_length-1 records are copied by calling Record::Record(const Record&) with the just created instance.
Since you haven't supplied a copy-ctor, the compiler has created one for you which simply does a bitwise copy of the object. Since vec_length is static to the class, nothing is to be copied - but also since the copy-ctor doesn't increment the static nothing happens (i.e. the value is simply retained).
So the output for these is 6.
您使用的向量构造函数的定义如下:
显式向量 ( size_type n, const T& value= T(), const Allocator& = Allocator() );
重复序列构造函数:初始化向量,其内容设置为值副本的重复 n 次。 这是 链接到手册页
我相信这意味着向量构造函数将运行您的默认构造函数一次(导致 6 次),然后您的复制构造函数再运行 4 次(导致更多6)。
The definition of the vector constructor you used is as follows:
explicit vector ( size_type n, const T& value= T(), const Allocator& = Allocator() );
Repetitive sequence constructor: Initializes the vector with its content set to a repetition, n times, of copies of value. Here is the link to the man page
I believe this means that the vector constructor will run your default constructor once (resulting in 6) and then your copy constructor 4 more times (resulting in more 6's).