You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

向C++类构造函数传递大量数据的最优方式及惯用法问询

代码示例

1. Tester类

class Tester
{
public:
    int m_tester_value;    

    Tester(){}

    Tester(int test_val)
    {
      m_tester_value = test_val;
    } 
    
    Tester(const Tester & data) : m_tester_value(data.m_tester_value)
    {
      std::cout << "Tester Copied!" << std::endl;
    }

    Tester& operator=(const Tester & data)
    {        
       m_tester_value = data.m_tester_value;

      return *this;
    }
};

2. VectorTester类

class VectorTester
{
  public:
    std::vector<Tester> m_vector;

  VectorTester(std::vector<Tester>* vector_construct)
  {
    if(vector_construct != nullptr)
    {
      m_vector = *vector_construct;
    }
  }

  VectorTester(const VectorTester & data) :       
                m_vector(data.m_vector)
  {
      std::cout << "VectorTester Copied!" << std::endl;
  }
      
};

3. TesterVectorGenerator函数

std::vector<Tester> TesterVectorGenerator(void)
{
  std::vector<Tester> ret_vector;
  ret_vector.reserve(2);

  ret_vector.emplace_back(65);
  ret_vector.emplace_back(75);

  return ret_vector;
}

4. 测试代码

int main() {
  std::vector<Tester> my_test_vector = TesterVectorGenerator();

  VectorTester vector_test = VectorTester(&my_test_vector);
    
  for (const auto &i : vector_test.m_vector)
  {
     // access by value, the type of i is int
     std::cout << "VectorTester.m_vector:" << i.m_tester_value << std::endl;
  }

  for (const auto &i : my_test_vector)
  {
     // access by value, the type of i is int
     std::cout << "my_test_vector:" << i.m_tester_value << std::endl;
  }  
}

输出结果

Tester Copied!
Tester Copied!
VectorTester.m_vector:65
VectorTester.m_vector:75
my_test_vector:65
my_test_vector:75

问题解答

1. 指针传递是否是最优方式?

不是。你用指针传递后,依然要执行m_vector = *vector_construct的拷贝操作,最终的拷贝次数和直接传值完全一致。而且指针传递存在空指针风险,需要额外做nullptr检查,反而增加了代码复杂度。

指针本身占4/8字节(取决于32/64位平台)确实比整个vector小,但传递指针并没有减少后续的拷贝开销——因为你最终还是要把整个vector复制到类成员里。这种方式不仅不比传const引用更优,还更不安全。

2. C++中传递此类数据的标准惯用法

针对你需要复制vector到类成员的场景,常用三种方式:

方式一:传递const引用

这是最常规的写法,避免不必要的临时拷贝,同时保证不会修改原数据:

VectorTester(const std::vector<Tester>& vec) : m_vector(vec) {}

调用时直接传对象:VectorTester vector_test(my_test_vector);,和指针传递的拷贝次数相同,但代码更简洁安全,无需处理空指针。

方式二:移动语义(原vector不再使用时)

如果不需要保留原my_test_vector的内容,可以用移动构造直接转移原vector的资源,完全避免拷贝开销:

VectorTester(std::vector<Tester>&& vec) : m_vector(std::move(vec)) {}

调用示例:

// 直接用函数返回值构造,自动触发移动
VectorTester vector_test(TesterVectorGenerator());
// 主动转移原vector的所有权
VectorTester vector_test(std::move(my_test_vector));

这种方式不会触发Tester的拷贝构造(输出里不会出现"Tester Copied!"),效率最高。

方式三:构造函数内直接生成vector

如果vector的生成逻辑和VectorTester强绑定,可以把生成逻辑放到构造函数里,省去外部传递步骤:

VectorTester() {
    m_vector.reserve(2);
    m_vector.emplace_back(65);
    m_vector.emplace_back(75);
}

额外代码优化建议

  • Tester类的默认构造函数可以删掉(如果不需要默认构造对象),或者用=default显式声明,符合现代C++风格。
  • Tester的拷贝构造和赋值运算符无需手动实现,编译器生成的默认版本已经能完成int成员的拷贝;如果只是为了观察拷贝行为可以保留,否则建议删除以减少冗余代码。
  • VectorTester的拷贝构造函数同理,编译器默认生成的版本已经能正确复制vector,日志仅用于调试时保留即可。

内容的提问来源于stack exchange,提问作者EmbeddedDOOD

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.21 01:48:38