2011-03-14 72 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