2011-03-14 64 views
2

我有一个结构/类是partiall普通旧数据(POD)。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; 
}; 

我复制S类的对象很多。 我想复制它与memcpy,但S ::更多阻止它。 我想避免调用4个memcpy,并使用它来获得额外的性能。 我应该这样做吗?

memcpy(s1, s2, sizeof(Pod1) + sizeof(Pod2) + sizeof(Pod3) + sizeof(Pod4); 

我无法将它们打包在单独的结构中,因为它会摧毁所有使用pod1 - pod4的代码。

什么是最佳解决方案?

回答

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

这是不是安全的,但也不能保证该结构被包装,有可能是空的空间,它们之间为了对齐的目的。

使用赋值和/或复制构造是安全的,除非通过探查器验证,否则它与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; 
} 
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; 
} 

,让编译器/连接器优化为你:它会比一个更好的方式工作您。而且你消除了将令人讨厌的bug带入游戏的风险(比如对齐,打包......)。

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)); 
+0

+1:聪明,应该想到这一点。 – Erik 2011-03-14 22:12:19