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; 

データ レイアウト オブジェクトは、それぞれのデータ メンバーとともに、宣言された順序で順番に配置されます。ここで同様の質問を見つけました:オブジェクトは C++ のメモリにどのように格納されていますか? 、しかし、出てきた追加の質問は、パブリックに加えてプライベートなど、異なるアクセスブロックがある場合はどうなるかということです? 違いはありますか?また、独自のデータ メンバーを持つ SomeClass のように、データ メンバーの 1 つが別のクラスである場合、どのように見えるでしょうか?

データメンバーアクセス 私が読んだこれは、オブジェクトへのポインター(「this」ポインターを想定)によって行われ、メンバーのサイズ/数量+パディングに応じて、いくらか移動します。繰り返しますが、プライベートメンバーと他のクラスとの違いはありますか? これは、Foo f と Foo g のデータ メンバーが互いに分離されていることがわかっている方法でもありますか。つまり、f.meth() を実行した場合、変更する正しい j をどのように選択しますか?

メンバー メソッドと非メンバー メソッド 関数が呼び出されると、関数はそれを呼び出したオブジェクトへのポインター ("this" ポインター) を受け取ります。これはメンバー関数の場合のようですが、非メンバー関数、つまりフレンド クラス Bar で何かがプライベート メンバー j を変更しようとするとどうなるでしょうか? それでは、「これ」は代わりに Bar オブジェクトになるのでしょうか? では、変更しようとしている Foo オブジェクトのデータ メンバーをどのように見つけるのでしょうか?

4

1 に答える 1

1

データレイアウト

パブリックに加えてプライベートなど、異なるアクセス ブロックがある場合はどうなりますか? 違いはありますか?

変わりはない。アクセス指定子は、メモリ レイアウトには影響しません。

また、独自のデータ メンバーを持つ SomeClass のように、データ メンバーの 1 つが別のクラスである場合、どのように見えるでしょうか?

メンバーはクラス オブジェクトにネストされ、その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 に答える