2012-10-14 32 views
-1

我想弄清楚Vec3b如何爲Opencv工作(但我認爲它更多的是關於基本C++的問題)。
源代碼如下(簡化):瞭解如何在C++中真實情況下將類變量存儲在內存中

template<typename _Tp, int m, int n> class CV_EXPORTS Matx 
{ 
    public: 
    // constructors, methods and operators 
    ... 
     _Tp val[m*n]; //< matrix elements 
}; 


// inherits from Matx 
template<typename _Tp, int cn> class CV_EXPORTS Vec : public Matx<_Tp, cn, 1> 
{ 
    public: 
    // constructors, methods and operators 
    ... 
}; 

typedef Vec<uchar, 3> Vec3b; 

例如我可以用它來從圖像讀取BGR的三聯體(像素):

int main(int argc, char** argv) 
{ 
    Vec3b* data= (Vec3b*)inputImage.data; 
    // access the 10th pixel 
    data[10] = Vec3b(0,0,255); 
} 

告訴我,如果我已經正確理解它。
inputImage.data是一個字節數組,包含BGR值和每行末尾的偏移量;因爲val是Matx的唯一數據成員,所以我們可以確定Vec3b是一組三個字節,所以當我考慮第10個指針時,我可以從第31個字節開始訪問或修改三個字節。
只有兩個問題:
1)爲什麼我們確信數據存儲在內存中的方式?僅僅因爲val是唯一的變量?
2)如果1.是真的,你不認爲這是一種危險的技術,因爲只添加第二個變量會使幾乎所有使用Vec2b的代碼不可用?

回答

1

這通常會在實踐中發揮作用,但也有一些潛在的缺陷。我們可以相對確定數據如何在內存中進行佈局,因爲C++非常特別地定義了從類定義到內存映射的佈局。變量將按照它們在類定義中指定的順序排列在內存中,儘管可以在變量之間插入填充以幫助對齊。由於這兩個項目都是相同基本類型的數組,我們可以確定每個元素的排列方式都是相同的。此外,指向第一個數據成員的指針通常會等於指向該對象本身的指針,但我認爲這隻適用於plain old data類型。在實踐中,對於不涉及虛擬功能的任何事情都是如此。

這是危險的方法,正如你所說的矩陣或vec2b的成員變量的任何變化會立即打破這一點。另外,添加任何虛擬方法會破壞這個功能,因爲vtable會在對象的開始處添加。

相關問題