我已经创建了2个班级。algorithm
和 peopleEncoding
:
peopleEncoding
有一个私人属性 _solution
这是个 std::vector
包含整数。algorithm
有一个私有属性 _population
这是个 std::vector
含有指向 solutionEncoding
的实例。该 algorithm
类也有一个叫做 initPopulation
充满 _population
像这样。
void initPopulation (unsigned peopleQuantity){
solutionEncoding * newOne = new solutionEncoding();
for (unsigned i = 0; i < peopleQuantity; i++ ){
newOne->generateRandom();
this->_population.push_back(newOne);
}
}
如果我打印 _solution
属性来自 peopleEncoding
实例存储在 _population
(刚到 push_back
行),我得到了预期的结果,但如果我在循环括号后做,向量就会发生变化(它们都是一样的,等于最后一个推送的)。
我不确定正确使用 new
.
这条线。
this->_population.push_back(newOne);
推回在最后的 _population
向量 newOne
指向 solutionEnconding
. 由于你只初始化了一个指针,所以它是指向同一个对象的同一个指针,而这个对象在所有的 _population
向量。
当你调用这个成员函数时,
newOne->generateRandom();
你可能会改变你的一些属性 solutionEncoding
的每一个元素,你似乎期待着。_population
因此,向量是随机的。 但事实并非如此,因为你只有一个对象。
为了达到你想要的目的,你需要在每次迭代中生成一个新的指向不同对象的指针。 只需移动带有 new
到循环中。 但这并不是一个好办法,因为你将不得不进行大量的内存管理(对每一个 new
,你需要一个 delete
),但有一定的风险(如浅层复制和双重删除)。
因此,一个更安全的方法是将 _population
含有以下内容的向量 solutionEncoding
对象。 newOne
也将是一个 solutionEncoding
对象。 push_back()
每次都会存储一个不同的副本。
std::vector<solutionEncoding> _population;
...
void initPopulation (unsigned peopleQuantity){
solutionEncoding newOne{}; // create a new local object - no 'new' needed
for (unsigned i = 0; i < peopleQuantity; i++ ){
newOne.generateRandom(); // shuffle all this data :-)
_population.push_back(newOne); // store a copy of the current data
}
}
如果solutionEncoding不是一个多态类的话,这就很好用了。 如果你打算派生出 solutionEncoding
类,这将无法工作,因为切片。 在这种情况下,你会使用一个 shared_ptr
:
std::vector<shared_ptr<solutionEncoding>> _population;
...
void initPopulation (unsigned peopleQuantity){
for (unsigned i = 0; i < peopleQuantity; i++ ){
auto newOne = make_shared<solutionEncoding>(); // create a different new object each time
newOne->generateRandom(); // shuffle all this data :-)
_population.push_back(newOne); // store the pointer to the new object
}
}