c++ - 如何高效初始化大类对象

标签 c++ class

假设我有一个包含多个 (+100) 个数据成员的类。对于这个问题,为了清楚起见,我们使用一个只有 6 个成员的示例:

class A
{
  public:
    int v1, v2, v3, v4, v5, v6;

    A(int a,
      int b,
      int c,
      int d,
      int e,
      int f)
        : v1(a),
          v2(b),
          v3(c),
          v4(d),
          v5(e),
          v6(f){};
};

现在,假设我要创建此类的单个 对象。由于成员数量众多,我想在一个单独的函数中初始化对象,以免弄乱 main。据我所知,我可以通过两种方式做到这一点:

方法一:

A test()
{
    return temp_a(1,2,3,4,5,6);
}

int main()
{
    A a = test();
}

方法二:(引用传递)

void test(vector<A>& a)
{
    A temp_a(1,2,3,4,5,6);
    a.push_back(temp_a);
}

int main()
{
    vector<A> a;
    test(a);
}

问题 在初始化大类的对象时,在效率专业性方面,这些方法中哪种方法最好?我个人更喜欢方法 2,因为我直接更改 vector 。缺点是每次我想访问对象的成员时都必须引用 a[0]

最佳答案

方法 2 的效率和 C++ 的惯用性都较低。

由方法 1 引起的复制和/或移动几乎肯定会被您的编译器忽略。返回值优化 (RVO) 将导致 A 对象在 test() 中的最终位置 (a) 中构造,就好像你写了类似的东西:

A * test(void *a)
{
    return new (a) A(1,2,3,4,5,6);
}

int main()
{
    typename std::aligned_storage<sizeof(A), alignof(A)>::type a_mem;

    A &a = *test(a_mem);

    // The rest of your code.

    // Technically this is not exception-safe, but for the purposes of
    // illustration, assume that the following line will be called even if
    // an exception is thrown between the line initializing the "a" reference
    // and this line.
    a.~A();
}

关键是,如果您认为这将成为性能瓶颈,那么您应该进行基准测试来验证这一点。编译器比我们聪明得多,它非常擅长优化掉很多东西。

任何瓶颈很可能出现在代码的其他地方。

让你的代码正确并且对 future 的维护者来说意义明显比寻求更高的性能更重要(除非你在关键路径上)。此外,与复杂的解决方法相比,编译器更容易优化简单直接的代码。 (例如,在方法 2 中,编译器无法轻松优化由 std::vector 引起的堆分配,因此您实际上是通过添加一个 去优化编译器无法看穿的额外间接级别。)

关于c++ - 如何高效初始化大类对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43850682/

相关文章:

javascript - 如何在 ES6 中使用私有(private)变量?

c++ - C++ 中原子更新最有效的 CAS 实现是什么?

c# - 有没有圆括号?有什么不同?

依赖于某些参数的 Java 类

c++ - 如何返回结构数组

javascript - jQuery - 将函数应用于具有相同类名的多个选择元素

使用类的 Python 前 20 个名称代码

c++ - pcap_next_ex() 永远不会将指针设置为原始数据包?

c++ - 我可以为并非所有非类型参数部分指定模板吗

c++ - shared_ptr 错误表达式必须有算术、枚举、指针