パブリック、プライベート、保護の舞台裏

Dec 08 2020

私はもっ​​と深く掘り下げて、パブリックとの違いを理解しようとしています。プライベート| C ++では、低レベルの観点から保護されています。

3つの違いは記憶にどのように表現されていますか?

回答

5 largest_prime_is_463035818 Dec 08 2020 at 20:48

privatepublicおよびprotectedメンバーがメモリの特定の領域に格納されることはありません。アクセスはコンパイラによってチェックされます。最下位レベルでは、違いはありません。

ただし、アクセス指定子は、クラスメンバーがメモリに配置される順序を保証するものに影響を与えます。

C ++ 17標準のドラフト:

同じアクセス制御(Clause [class.access])を持つ(非ユニオン)クラスの非静的データメンバーは、後のメンバーがクラスオブジェクト内でより高いアドレスを持つように割り当てられます。異なるアクセス制御を持つ非静的データメンバーの割り当ての順序は指定されていません([class.access]節)。実装の調整要件により、2つの隣接するメンバーがすぐに割り当てられない場合があります。仮想関数([class.virtual])と仮想基本クラス([class.mi])を管理するためのスペースの要件も同様です。

つまり、

 struct foo {
     private:
        int x;
     protected:
        int a;
        int b;
     public:
        int m;
        int n;
     private:
        int y;
};

あなたは、メモリ内xが前ya来て、前bm来て、前に来るという保証を得るだけですn。それ以外は、メンバーがメモリに配置される順序は指定されていません。

ただし、メモリ内のメンバーの順序が有用な情報になることはめったにありません。したがって、アクセス指定子が「低レベルのメモリ」とは何の関係もないと言っても間違いではありません。

2 SergeBallesta Dec 08 2020 at 20:44

最下位レベル(オブジェクトのバイト表現)では、パブリック、プライベート、および保護の間にまったく違いはありません。ほとんどのコンパイラは、可視性に応じてメンバーを並べ替えることができます(必須ではありません)。

中間レベル(実行時の動作)では、違いはほとんどありません。プライベートデータへのパブリックポインタを見つけることができれば、それを安全に使用できます。具体的には、これは、非constポインタを使用してconstデータを変更することが明示的に未定義の動作であり、SIGSEGVエラーを引き起こす可能性があるconstnessとは異なります。

違いは最高レベルのみです。パブリックメンバーはどこからでも使用できますが、プライベートメンバーは宣言されたクラスでのみ使用でき、保護されたメンバーはクラスとそれを継承するすべてのクラスから使用できます-ただし、友情により、特定のクラスの関数がプライベートまたは保護されたクラスにアクセスできますデータ。

Yunnosch Dec 08 2020 at 20:35

どういたしまして。

アクセスはコンパイラによって「許可/拒否」されます。

適切な可視性と一致しないアクセス(ポインタを介して、またはアクセスされていないオブジェクトのクラスによって制御される)は、ビルドする前に防止されます。

注意:

他の回答は、メモリ内の順序に対する可視性の影響について有益に説明しています。

OPの投稿「メンバーのアクセス可能性/可視性を実装するためにメモリ保護機能はどのように使用されますか?」に読んだ別の質問にhowevrが答えました。これは、原因と結果に関する逆の質問の一種です。または、異なる構成のメモリ内のメンバーの順序付け/構造化のみが、目的の可視性効果を実現するためのツールであり、これにより、メンバーを特定の方法で順序付けする必要があります(ただし、原因にはなりません)。

つまり、回答の間に矛盾は見られず、質問の解釈が異なるだけです。