C++ 了解类变量在c+中实际情况下如何存储在内存中+;

C++ 了解类变量在c+中实际情况下如何存储在内存中+;,c++,opencv,C++,Opencv,我正试图弄清楚Vec3b是如何为Opencv工作的(但我认为这更像是一个关于基本c++的问题)。 源代码如下(简化): 告诉我我是否理解正确。 数据是一个字节数组,包含每行末尾的BGR值和偏移量;由于val是Matx的唯一数据成员,我们可以确定Vec3b是一个由三个字节组成的集合,因此当我遵从第10个指针时,我可以访问或修改三个字节,从第31个字节开始。 只有两个问题: 1) 为什么我们确定数据存储在内存中的方式?只是因为val是唯一的变量? 2) 如果1。是的,您不认为这是一种危险的技术,

我正试图弄清楚Vec3b是如何为Opencv工作的(但我认为这更像是一个关于基本c++的问题)。
源代码如下(简化):

告诉我我是否理解正确。
数据是一个字节数组,包含每行末尾的BGR值和偏移量;由于val是Matx的唯一数据成员,我们可以确定Vec3b是一个由三个字节组成的集合,因此当我遵从第10个指针时,我可以访问或修改三个字节,从第31个字节开始。
只有两个问题:
1) 为什么我们确定数据存储在内存中的方式?只是因为val是唯一的变量?

2) 如果1。是的,您不认为这是一种危险的技术,因为只添加第二个变量会使几乎所有使用Vec2b的代码都不可用吗

这在实践中通常是可行的,但也存在一些潜在的陷阱。我们可以比较确定数据如何被放置在内存中,因为C++定义了从类定义到内存布局的映射。变量在内存中的排列顺序与在类定义中指定的顺序相同,尽管可以在变量之间插入填充以帮助对齐。由于这两个项都是相同基类型的数组,我们可以确保每个元素的对齐方式相同。此外,指向第一个数据成员的指针通常与指向对象本身的指针相等,尽管我认为这只适用于类型。在实践中,这对于任何不涉及虚拟函数的情况都是正确的

这是危险的,正如您所提到的,矩阵或vec2b的成员变量的任何更改都会立即破坏这一点。此外,添加任何虚拟方法都会破坏这一点,因为vtable将添加到对象的开头

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; 

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