1

我试图了解 C++ 在内存中的布局方式、数据成员的访问方式和方法调用方式方面是如何工作的,但发现它非常令人困惑。当涉及到一个不涉及继承、虚函数等的非常简单的类时,我可以澄清一下我是否在这些概念的正确轨道上。

   class Foo
    {
    public:
        Foo(); 
        int i;
        char c;
        void meth(); // sets private member j 
    private:
        int j; 
        SomeClass s;  
        friend class Bar; 
    };

Foo f;
Foo g; 

数据布局 对象将按照它们声明的顺序以及它们各自的数据成员顺序排列。我在这里发现了一个类似的问题:How are objects stored in memory in C++? ,但出现的另一个问题是,如果有不同的访问块,比如除了公共之外的私有访问块,会发生什么?有什么区别吗?此外,如果其中一个数据成员是另一个类,例如 SomeClass 具有自己的数据成员,它会是什么样子?

我读到的数据成员访问 是通过指向对象的指针(假设“this”指针)完成的,该指针会根据成员的大小/数量+填充来移位一定量。同样,私有成员和其他类有区别吗?这也是已知 Foo f 和 Foo g 的数据成员彼此分开的方式,即如果我做了 f.meth(),它如何选择正确的 j 来改变?

成员与非成员方法 当函数被调用时,它会收到一个指向调用它的对象的指针,即“this”指针。这似乎是成员函数的情况,但是如果一个非成员函数,比如朋友类 Bar 中的某些内容,试图修改私有成员 j,会发生什么?那么“这个”肯定会是一个 Bar 对象吗?那么它如何在它试图修改的 Foo 对象中找到数据成员呢?

4

1 回答 1

1

数据布局

如果有不同的访问块,比如私有和公共,会发生什么?有什么区别吗?

没有不同。访问说明符对内存布局没有影响。

此外,如果其中一个数据成员是另一个类,例如 SomeClass 具有自己的数据成员,它会是什么样子?

成员将SomeClass嵌套在类对象中,其成员的顺序与它们在非成员SomeClass对象中出现的顺序相同。

数据成员访问

同样,私有成员和其他类有区别吗?

再次,不。

这也是已知 Foo f 和 Foo g 的数据成员彼此分开的方式,即如果我做了 f.meth(),它如何选择正确的 j 来改变?

让我们假设这是Foo::meth()

void Foo::meth()
{
    j++;
}

这相当于:

void Foo::meth()
{
    this->j++;
}

其中,当分别调用Foo对象f和时g,等效于:

f.j++;    // this is, of course, not legal as j is private
g.j++;

成员与非成员方法

如果一个非成员函数,比如朋友类 Bar 中的某事,试图修改私有成员 j,会发生什么?那么“这个”肯定会是一个 Bar 对象吗?

是,对的。

那么它如何在它试图修改的 Foo 对象中找到数据成员呢?

好吧,它不能像使用Bar. 它需要通过一个Foo对象来访问它。成员Foo对象、全局Foo对象或Foo作为参数传递给函数的对象。例如

void Bar::DoSomethingWithFoo(Foo & f)
{
    // j = 10; <-- can't do this, unless Bar has a member named j
    //            but in that case, it has no effect on the j member
    //            of f

    f.j = 10;
}
于 2013-11-08T02:44:10.757 回答