构造过程中对向量中元素的引用

Posted

技术标签:

【中文标题】构造过程中对向量中元素的引用【英文标题】:References to elements in vectors during construction 【发布时间】:2015-09-23 14:09:20 【问题描述】:

在 C++ 中,我有一个类 MyClass,它在构造过程中引用 int 来创建对它的内部引用。

然后我有一个类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 包含引用而不是指针,因此引用的值不能被修改。

【问题讨论】:

vecInt_vecMyClass_ 必须是 const 吗? 不会添加/删除向量的任何元素,但是会修改存储在向量中的值。 【参考方案1】:

您可以在构造 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]);
    

【讨论】:

【参考方案2】:

这听起来不是一个好主意。在某些时候,向 vecMyInt_ 添加元素将导致向量扩展,即分配新内存并将元素移动到那里,并释放旧内存。这意味着 MyClass 的实例保存的引用将是无效的。

当然,如果你事先预留了容量,并且从不向向量中添加元素,这当然不是问题。

【讨论】:

【参考方案3】:
#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 b10;
  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;

【讨论】:

以上是关于构造过程中对向量中元素的引用的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++ 中对向量组元素进行排序?

使用 NEON 在 ARM 汇编中对四字向量中的所有元素求和

构造函数中的引用向量:未初始化的引用

JAVA笔记---面向过程与面向对象;类,对象;实例变量,引用;构造方法;

new实例化函数的过程

如何从函数返回向量引用?