如何有效地初始化大型类的对象

How to efficiently initialize objects of large class

本文关键字:对象 大型 初始化 有效地      更新时间:2023-10-16

>假设我有一个包含多个(+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();
}

方法2:(通过引用传递)

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,因为我直接更改向量。缺点是每次我想访问对象的成员时都必须引用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();
}

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

任何瓶颈很可能都位于代码中的其他位置。

使你的代码对未来的维护者来说正确和明显,比提高一点性能更重要(除非你走在关键路径上)。 此外,编译器优化简单明了的代码比优化复杂的解决方法要容易得多。 (例如,在方法 2 中,编译器无法轻松优化由std::vector引起的堆分配,因此您实际上是通过添加编译器无法透视的额外间接级别来取消优化