我有一个struct / class,它是partiall Plain Old Data(POD)。
struct S {
// plain-old-data structs with only arrays and members of basic types (no pointers);
Pod1 pod1;
Pod2 pod2;
Pod3 pod3;
Pod4 pod4;
vector<int> more;
};
我经常复制S类的对象。 我想用memcpy复制它,但S :: more阻止了它。 我想避免调用4个memcpy,并将其全部用于一个额外的性能。 我应该这样做吗?
memcpy(s1, s2, sizeof(Pod1) + sizeof(Pod2) + sizeof(Pod3) + sizeof(Pod4);
我无法将它们打包在单独的结构中,因为它会破坏使用pod1-pod4的所有代码。
什么是最佳解决方案?
答案 0 :(得分:10)
最好的解决方案是依靠C ++自动复制构造函数和复制运算符。然后,编译器有机会理解您的代码并对其进行优化。尽量避免使用C ++代码中的memcpy。
如果您只需要复制部分结构,请为其创建一个方法:
struct S {
// plain-old-data structs with only arrays and members of basic types (no pointers);
Pod1 pod1;
Pod2 pod2;
Pod3 pod3;
Pod4 pod4;
vector<int> more;
};
void copyPartOfS(S& to, const S& from)
{
s.pod1 = from.pod1;
s.pod2 = from.pod2;
s.pod3 = from.pod3;
s.pod4 = from.pod4;
}
...
S one, two;
one = two; // Full copy
copyPartOfS(one, two); // Partial copy
答案 1 :(得分:2)
作为@Erik said,您拥有的代码因填充而无效。
但是,由于您没有使用任何访问声明,因此编译器需要按照与源代码相同的顺序存储字段,因此您可以这样做:
struct S {
// plain-old-data structs with only arrays and members of basic types (no pointers);
Pod1 pod1;
Pod2 pod2;
Pod3 pod3;
Pod4 pod4;
vector<int> more;
};
memcpy(&s1.pod1, &s2.pod1, (char*)(1 + &s1.pod4) - (char*)(&s1.pod1));
答案 2 :(得分:1)
这是不安全的,不能保证结构被打包,它们之间可能有空的空间用于对齐目的。
使用赋值和/或复制构造是安全的,并且在使用分析器进行验证之前,它与memcpy一样快。)。
编辑:如果你真的想使用memcpy,这是一个可能但可怕的解决方案:
struct S1 {
Pod1 P1;
Pod2 P2;
};
struct S : S1 {
vector<int> more;
};
void copy(S & Dest, S const & Src) {
memcpy(&Dest, &Src, sizeof(S1));
Dest.more = Src.more;
}
答案 3 :(得分:1)
void CopyPods(Struct S& s1, Struct S& s2)
{
s2.pod1=s1.pod1;
s2.pod2=s1.pod2;
s2.pod3=s1.pod3;
s2.pod4=s1.pod4;
}
让编译器/链接器为你优化它:它会比你做得更好。并且你消除了将令人讨厌的错误带入游戏的风险(例如对齐,打包......)。