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