3

私が理解していることから、C++ クラスの非静的データ メンバーは C スタイルの構造体にパックされます。この議論を単純化するために仮想関数と継承を無視すると、アクセス指定子はそのようなスキームでどのように適用されるのでしょうか?

クラスを言う:

class Object
    {
public:
    int i1;
    int i2;
private:
    char i3;
    int i4;
    };

に変換します。

struct { 
  int i1;
  int i2;
  char i3;
  int i4;
}

c++ はどのようにプライベート メンバーi3を保証しi4、クラスの外部ではアクセスできませんが、アクセスi1できるi2ようにしますか?

4

4 に答える 4

5

C ++には、マキャヴェリではなく、マーフィーから保護するための(いくつかの)セーフガードがあります。

これが意味するのはconst、、volatileおよびアクセス修飾子はコンパイル時にチェックされますが、それでもバイパスすることができます(さまざまなトリックで)。

つまり...C++は保護スキームを実装する必要はありません。プログラムがコンパイルされた場合、それは正しいと見なされ(これらの修飾子を使用)、実行時チェックなしで実行されます。

于 2012-06-11T07:00:07.420 に答える
3

そうではありません。先に進み、reinterpret_cast手動でポインターにインデックスを付けます。constこれは、C と C++ の両方でキャスト アウェイが許可されているのと同じ理由です。

ただし、一般的に言えば、そうするのはばかげた考えであり、C++ は、通常の方法でアクセスするときに修飾子をチェックするだけで、アクセス修飾子を効果的に強制します。

于 2012-06-11T06:49:29.637 に答える
1

C++ は静的に型付けされた言語です。同様に、C++ の概念の多くも静的にチェックされます。特に、アクセス指定子はコンパイル時にチェックされます。

この標準では、クラスのメンバーがメモリ内でどのように配置されるかについて、いくつかの保証が与えられています。最も便利なのは、同じアクセス指定子セクションで一緒に指定されたメンバーが、指定された順序で使用できることです。(これは、ネットワーク パケットにアクセスする場合などに非常に役立つ特性です。)

あなたの質問に答えるために、構造体への「変換」はありません(構造体は、デフォルトのアクセスがプライベートではなくパブリックである縮退クラスです)。アクセス指定子はコンパイル時に適用されます。アクセス指定子の実行時の強制はありません。

于 2012-06-15T16:04:24.063 に答える
0

あなたの情報源は何ですか?オブジェクトがメモリ内でどのように表現されるかを指していると思いますが、アクセス指定子を扱うのはランタイムではなくコンパイラです。

メモリ内では aは aと同じに見えるclass かもしれませんstructが、コンパイラにはそうではありません。

また、この 2 つはメモリ内でも同等である必要はありません (コンパイラーで同等ではないのと同じように)。コンパイラは、インターリーブ アクセス指定子を持たないメンバーをまとめて保持する限り、メンバーを再配置できます。では、記憶の中で、

class Object {  
public: 
   int i1; 
   int i2; 
private: 
   char i3; 
   int i4; 
};

理論的には次のように表すことができます

struct {
   char i3;
   int i4;
   int i1;
   int i2;
}

ここでは、メモリ レイアウトについてのみ説明していることに注意してください。クラスの実際の同等物は次のとおりです。 struct

struct Object {  
private:
public: 
   int i1; 
   int i2; 
private: 
   char i3; 
   int i4; 
};
于 2012-06-11T06:49:15.363 に答える