对象如何存储在内存中?嵌入基类与创建基类成员对象

How Objects stored in memory? Inherting a Base Class vs. Creating a Base Class Member Object

提问人:Azriel Elijay 提问时间:2/17/2023 更新时间:2/17/2023 访问量:40

问:

class Base
{
public:
    int nX;
    int nY;
    Base(){};
    ~Base(){};
};

class Derived
{
private:
    Base pBase;
    int mX;
    int mY;
public:
    Derived(){}
    Derived(int x , int y) { pBase.nX = x; pBase.nY = y;}
    ~Derived(){}
    void Print()
    {
        std::cout<<"Base X is "<< pBase.nX << ", Base Y is " << pBase.nY << std::endl;
    }
};

int main() 
{
    Derived pDerived(10,9);
    Base* pBase = reinterpret_cast<Base*>(&pDerived);
    pDerived.Print();
    std::cout<<"Cast X is "<< pBase->nX<<", Cast Y is "<< pBase->nY<<std::endl;
    return 0;
}

我在 Source 中遇到了上面的东西,它没有继承基类,但将其作为类/结构的一部分包含在内,作为基指针发送到另一个消费者函数,然后根据 的值将其转换为 Derived 类(或其他类)。reinterpret_castnX

nX保证每个类都是独一无二的,至少从我从源头看到的是这样。

我已经过度简化了它对代码的用法,我之所以称它为,是因为缺乏更好的术语,因为我完全不知道该怎么称呼这种做法BaseDerived

代码似乎确实获取了正确的地址,并且确实输出了 和 的正确值,并且应用程序逻辑也确实有效。与我的示例不同,除了默认构造函数之外,这些类没有任何函数。我还在我的示例中保留了类,成员变量位于构造函数/成员函数之上。nXnYvirtualstructure

我的问题是,对象如何自动或动态地存储在内存中,是否保证以这种方式运行(存储类似于此线程上的答案中所述的结构,给定上面的代码。或者这是一种未定义的行为,如果不修复此问题,最终会遇到分段错误访问冲突

C++ 可视化工作室-2008

评论

2赞 apple apple 2/17/2023
这回答了你的问题吗?将指针指向其第一个成员是非法的吗?
0赞 Azriel Elijay 2/17/2023
@appleapple我阅读了该线程,我发布了问题,因为我还没有最微弱的想法,实践的名称是什么,并且线程的示例是针对动态对象的,我不确定它是否仍然适用于自动对象,特别是在 VS2008 上。
0赞 apple apple 2/17/2023
@ AzrielElijay指针互换性与(自动/动态)存储持续时间无关。
0赞 apple apple 2/17/2023
我不知道 VS2008 会做什么,也不知道它是否有任何错误,fwiw。

答:

0赞 leosch 2/17/2023 #1

当代码将另一个类的实例保留为其成员时,它使用组合而不是继承。仅当成员是第一个成员时,演员表才有效。reinterpretpBase

在它前面添加另一个成员后,您的代码将具有 UB,请参阅示例:https://www.godbolt.org/z/3ocr9q5Ts

有关更多详细信息,请参阅将指针指向其第一个成员是否非法?