2

次の 2 つのクラス定義があるとします (アクセス指定子のみbar()が異なり、他のすべては同じです)。

class MyClass {
public:
    void foo();
    void bar();   // bar() is public

private:
    int member;
};

class MyClass {
public:
    void foo();

private:
    void bar();   // bar() is private
    int member;
};

コンパイラは、コンパイラが生成するコードに関してクラスが「異なる」と見なしますか? (つまり、コンパイラは、アクセス許可のチェックとは別に、別の方法で処理しますか?)

これは次の質問と同じです: 次のコードはundefined behaviorのような問題を引き起こしますか? (ただし、X が定義されているかどうかに関係なく、異なるユニットでコンパイルされ、後で相互にリンクされます。)

class MyClass {
public:
    void foo();

#ifdef X
private:
#endif
    void bar();

private:
    int member;
};

コンパイラに依存しない回答と、GCC 固有の回答に興味があります (これが私の主要なターゲット コンパイラであるため)。

package private「パッケージ」内で特定のマクロを定義することにより、C++ で Java の世界のようなものを「シミュレート」したい場合、これは興味深いものになります。

4

2 に答える 2

4

同じクラス型のすべての定義が同一である必要があるという 1 つの定義規則に違反することは、明らかに未定義の動作です。

クラスのメモリ レイアウトは、各アクセス レベル内でのみ指定されることに注意してください。そのため、アクセス レベルを変更すると、非常に現実的にクラスのメモリ レイアウトが異なる可能性があります。

于 2012-09-27T21:11:40.387 に答える
1

これは良い考えではないように思われます:

一部の関数またはデータメンバーへのアクセス権を、たとえばプライベートからパブリックに変更します。一部のコンパイラでは、この情報が署名の一部である場合があります。プライベート関数を保護またはパブリックにする必要がある場合は、プライベート関数を呼び出す新しい関数を追加する必要があります。

―C++でのポリシー/バイナリ互換性の問題

ただし、これによって未定義の動作が発生するのではなく、リンクエラーまたはシンボルの読み込みエラーが発生するはずです。

アップデート:

GCC(4.6.1)でのテストでは、アクセス権の変更は問題なく機能しました。

于 2012-09-27T20:36:18.200 に答える