2013-11-26 87 views
1

我有兩個類和我的轉換方法:集裝箱鑄造

class A; 
class B; 

class A 
{ 
    ... 
}; 

class B 
{ 
    ... 

    static B fromA(A a) 
    { 
     B b; 
     // ... some property conversions from A to B 
     return b; 
    } 
    operator A() 
    { 
     // ... some property conversions from this(B) to A 
     return A 
    } 
} 

如可以看到的我所定義的流延(對於B - > A)+靜態轉換(對於A - > B)B類內它是被禁止的定義A級內的任何轉換或轉換

假設我有兩個向量:

vector<vector<A> > vecA; // pre-defined 
vector<vector<B> > vecB; // to be casted from vecA 

什麼是最佳(最快)的方式來實現這些之間的數據轉換,我的醜陋的解決方案代替:

using namespace std; 

vecB.resize(vecA.size()); 
for(int i = 0; i<vecA.size(); i++) 
{ 
    vecB[i].resize(vecA[i].size()); 
    for(int j = 0; j<vecA[i].size(); j++) 
    { 
     vecB[i][j] = B::fromA(vecA[i][j]); 
    } 
} 

回答

2

在代碼變化定義operator =對於B

B::operator=(const A& a) 
{ 
// actual code to copy from a to b. 
} 

vecB[i][j] = B::fromA(vecA[i][j]); 

vecB[i][j] = vecA[i][j]; 

它將消除許多臨時了在創建的&乙對象你的原始代碼。

而不是使用vecB [i] [j]使用迭代器。下面的代碼可能有一些語法錯誤

vecB.resize(vecA.size()); 

vector<vector<A> >::const_iterator itA1; 
vector<vector<B> >::const_iterator itB1; 
vector<A> >::const_iterator itA2; 
vector<B> >::const_iterator itB2; 


for(itA1=vecA.begin(), itB1= vecB.begin(); 
     itA1 != vecA.end(); 
     ++itA1, ++itB1) 
{ 
    for(itA2 = (*itA1).begin(), itB2=(*itB1).begin(); 
     itA2 != (*itA1).end(); 
     ++itA2, ++itB2) 
    { 
     (*itB2) = *itA2; 
    } 
} 
+0

您應該在複製 –

1

,如果你想(這可能是,如果你的標準庫實現高度優化的快一點)可以使用算法和迭代器代替手工製作for循環,但核心複雜性保持不變 - 你必須單獨轉換每個元素,沒有辦法。

1

而不是定義:

static B fromA(A a); 

定義:

B(A a)作爲轉換構造

通常這是通過使用explicit關鍵字避免,但在這裏,這似乎正是你想要,因爲什麼你需要構建一個B從A

這會簡化:

vecB[i][j] = B::fromA(vecA[i][j]); 

到:

vecB[i][j] = vecA[i][j]; 

它看起來像一個很好的候選人'的std ::複製

+0

謝謝,std :: copy對於循環來說有兩個相同的複雜度。但是,使用構造函數或某個運算符消除臨時B對象似乎非常關鍵。 – baci

1

您可以使用std::transform使你的代碼有點短,更易於閱讀。但是,如果您定義方法B fromA(A a)是一種無效方法,並且採用類型爲B&的輸出參數,則我認爲您將獲得最佳性能。即使您的方法聲明static void fromA(const A&, B&)。這種方式對於pre-C++ 11代碼,您將避免返回對象的副本。

或者使方法fromA代替靜態方法的實例方法,並再次使其無效 - 該方法將修改當前實例。另一個選項與其他答案中指出的一樣 - 創建一個以const A&作爲其唯一參數的B的構造函數。

1

您可以定義的隱式轉換構造函數A轉換爲B,而不是一個命名函數:

B(A const & a) { 
    // ... some property conversions from A to B 
} 

現在,你可以在一個向量轉換的東西,如

std::vector<B> vecB(vecA.begin(), vecA.end()); // declare a new vector 
vecB.assign(vecA.begin(), vecA.end());   // reassign an existing vector 

你仍然需要一個循環來重新分配向量的向量;可能是這樣的:

vecB.clear(); 
vecB.reserve(vecA.size()); 
for (auto const & vA : vecA) { 
    vecB.push_back(std::vector<B>(vA.begin(), vA.end())); 
} 

這不會比你的版本更快,但涉及寫更少的代碼。

+0

isnt push_back之前使用'std :: vector :: resize()'而不是調整大小+賦值? – baci

+0

@C.CanberkBacı:如果您事先預留了足夠的空間,則不需要。 –

0

如果你想編寫好的代碼,你可以使用std::transformstd::assign,或std::for_each但如果你想快速的代碼,那麼這將是很難寫的東西比這更快:

vecB.resize(vecA.size()); 
for (unsigned int i = 0, asize = vecA.size(); i < asize; i++) 
{ 
    const vector<A> & vin = vecA[i]; 
    vector<A> & vout = vecB[i]; 

    vout.resize(vin.size()); 
    for (unsigned int j = 0, bsize = vout.size(); j < bsize; j++) 
    { 
     vout[j].createFromA(vin[j]); 
    } 
} 

通知的asize和初始化是這樣完成的,以防止混疊問題。 也createFromA應該是一個成員函數,直接初始化類成員沒有其他類複製/分配。