构造期间对向量中元素的引用
References to elements in vectors during construction
在 C++ 中,我有一个 class MyClass
,它在构造过程中引用了一个 int
以创建对它的内部引用。
然后我有一个 class BigClass
,其中包含一个 std::vector<int> vecInt_
和一个 std::vector<MyClass> vecMyClass_
。 BigClass
的构造函数将向量 vecInt_
和 vecMyClass_
的大小作为参数。在 BigClass
的构造函数中,我想让 vecMyClass_
的每个元素在其构造函数中使用 vecInt_
的相应元素。
我怎么写的?如果我可以从 BigClass 的构造函数的主体调用 vecMyClass
的构造函数,那将是这样的:
BigClass(int nbElem) :
vecInt_(nbElem),
vecMyClass_(nbElem)
{
for (int i = 0; i < nbElem; ++i)
{
vecMyClass_[i](vecMyInt_[i]);
}
}
但是这里的括号当然是指operator()
,而不是构造函数。我不能写这样的东西:
vecMyClass_[i] = MyClass(vecMyInt_[i]);
因为 MyClass 包含的是引用而不是指针,因此不能修改引用的值。
您可以将 vecMyClass_
初始化为一个空向量,并在构造它们时将 emplace_back
个元素初始化为它:
BigClass(int nbElem) :
vecInt_(nbElem),
vecMyClass_() //empty vector
{
vecMyClass_.reserve(nbElem); //avoid reallocations
for (int i = 0; i < nbElem; ++i)
{
vecMyClass_.emplace_back(vecInt_[i]);
}
}
#include <vector>
#include <iostream>
struct MyClass {
int& x;
MyClass(int& x) : x(x) {}
};
struct BigClass {
BigClass(std::size_t nb_elems) : ints(nb_elems) {
my_classes.reserve(nb_elems);
for(int& x : ints) {
my_classes.emplace_back(x);
}
}
std::vector<int> ints;
std::vector<MyClass> my_classes;
};
int main()
{
BigClass b{10};
for(int& x : b.ints) {
x = 23;
}
// they are all 23
for(auto& c : b.my_classes) {
std::cout << c.x << std::endl;
// change them
c.x = 24;
}
// they are all 24 now
for(auto& c : b.ints) {
std::cout << c << std::endl;
}
return 0;
}
这听起来不是个好主意。在某些时候向 vecMyInt_ 添加元素将导致向量扩展,即分配新内存并将元素移动到那里,并释放旧内存。这意味着 MyClass 实例保留的引用将无效。
当然,如果您事先预留了容量,并且从不向向量中添加元素,这就不会成为问题。
在 C++ 中,我有一个 class MyClass
,它在构造过程中引用了一个 int
以创建对它的内部引用。
然后我有一个 class BigClass
,其中包含一个 std::vector<int> vecInt_
和一个 std::vector<MyClass> vecMyClass_
。 BigClass
的构造函数将向量 vecInt_
和 vecMyClass_
的大小作为参数。在 BigClass
的构造函数中,我想让 vecMyClass_
的每个元素在其构造函数中使用 vecInt_
的相应元素。
我怎么写的?如果我可以从 BigClass 的构造函数的主体调用 vecMyClass
的构造函数,那将是这样的:
BigClass(int nbElem) :
vecInt_(nbElem),
vecMyClass_(nbElem)
{
for (int i = 0; i < nbElem; ++i)
{
vecMyClass_[i](vecMyInt_[i]);
}
}
但是这里的括号当然是指operator()
,而不是构造函数。我不能写这样的东西:
vecMyClass_[i] = MyClass(vecMyInt_[i]);
因为 MyClass 包含的是引用而不是指针,因此不能修改引用的值。
您可以将 vecMyClass_
初始化为一个空向量,并在构造它们时将 emplace_back
个元素初始化为它:
BigClass(int nbElem) :
vecInt_(nbElem),
vecMyClass_() //empty vector
{
vecMyClass_.reserve(nbElem); //avoid reallocations
for (int i = 0; i < nbElem; ++i)
{
vecMyClass_.emplace_back(vecInt_[i]);
}
}
#include <vector>
#include <iostream>
struct MyClass {
int& x;
MyClass(int& x) : x(x) {}
};
struct BigClass {
BigClass(std::size_t nb_elems) : ints(nb_elems) {
my_classes.reserve(nb_elems);
for(int& x : ints) {
my_classes.emplace_back(x);
}
}
std::vector<int> ints;
std::vector<MyClass> my_classes;
};
int main()
{
BigClass b{10};
for(int& x : b.ints) {
x = 23;
}
// they are all 23
for(auto& c : b.my_classes) {
std::cout << c.x << std::endl;
// change them
c.x = 24;
}
// they are all 24 now
for(auto& c : b.ints) {
std::cout << c << std::endl;
}
return 0;
}
这听起来不是个好主意。在某些时候向 vecMyInt_ 添加元素将导致向量扩展,即分配新内存并将元素移动到那里,并释放旧内存。这意味着 MyClass 实例保留的引用将无效。
当然,如果您事先预留了容量,并且从不向向量中添加元素,这就不会成为问题。