为什么C ++在迭代容器时会调用复制构造函数?

时间:2012-08-23 09:01:44

标签: c++ copy-constructor

void ParticleGeneratorController::generate() {
    for( unsigned i = 0; i < generators.size(); i++) {
        ParticleGenerator generator = *generators[i];
        generator.update();
    }
}

似乎调用了复制构造函数或其他东西,但我没有定义一个。我只有一个显式的默认构造函数。

https://github.com/ChrisLundquist/Waveform/blob/master/src/models/particle_generator.h

鉴于我的上述代码,测试失败。 https://github.com/ChrisLundquist/Waveform/blob/master/spec/controllers/particle_generator_controller_spec.cpp#L21

写为

void ParticleGeneratorController::generate() {
    for( unsigned i = 0; i < generators.size(); i++) {
        generators[i]->update();
    }
}

测试通过。

为什么在第一个实现中调用了复制构造函数?它是如何由编译器生成的?

3 个答案:

答案 0 :(得分:5)

此行会导致副本:

ParticleGenerator generator = *generators[i];

如果未显式指定复制构造函数(或赋值运算符),则编译器会自动生成一个。如果您希望阻止复制对象,可以将复制构造函数和赋值运算符声明为private,而不是将其定义为:

ParticleGenerator
{
public:

private:
    ParticleGenerator(const ParticleGenerator&);
    ParticleGenerator& operator=(const ParticleGenerator&);
};

答案 1 :(得分:5)

每次执行此操作时,您都在创建新的ParticleGenerator

ParticleGenerator generator = *generators[i];

这是一个复制初始化,并且,如果您没有显式提供复制构造函数,则使用编译器合成的构造函数。

答案 2 :(得分:0)

以下行是副本:

ParticleGenerator generator = *generators[i];

如果您没有定义复制构造函数,编译器会自动为您执行此操作。为了禁用它,您可以将复制构造函数声明为私有而不实现它。通常也应该使用复制赋值运算符来完成。

如果您想避免在代码中复制,可以简单地创建一个指针。写

ParticleGenerator * generator = generators[i];
generator->update();

进入你的循环。或者

generators[i]->update();

如果你想真正做空。