9

今、私はインライン関数について学んでいますが、本当に混乱する何かに遭遇しました

このクラスを見る

class Nebla{
private:
    int x;
public:
    inline void set(int y){x=y;}
    inline void print(){cout<<x<<endl;}
};

プライベート データ メンバーがあります。int x;

また、次の 2 つのパブリック インライン関数がset(int y) あります。print()

これら 2 つの関数はインラインであるため、呼び出されると、コンパイラは関数呼び出しを関数の内容に置き換えます。

だから私はこれを行う場合

Nebla n;
n.set(1);
n.print();

2 つの関数はインラインであるため、次のようになります。

Nebla n;
n.x=1;
cout<<n.x<<endl;

でもちょっと待って、xプライベートです。したがって、これは機能しません。

しかし、通常はクラス外からプライベートメンバーにアクセスできないのに、なぜ機能するのか混乱していますか?

クラスの外部からプライベートデータメンバーにアクセスできる理由を説明できますが、メンバー関数がインラインの場合、インラインは関数呼び出しを関数の内容に置き換えるだけですが、アクセスできますか?

4

4 に答える 4

11

データメンバーの保護は純粋に概念的なものです。コンパイラレベルでのみ存在します。コンパイラがソースコードを変換するときにチェックされ、適用されます。コードがコンパイルされると、パブリックデータメンバーとプライベートデータメンバーの間に違いはなくなります。つまり、アクセス制御を強制し、プライベートデータメンバーへのアクセスを防ぐ物理的なメカニズムはありません。

メンバーアクセスは、言語仕様に従ってコンパイラーによって強制されます。言語仕様では、クラスメンバー関数は(インラインであるかどうかに関係なく)クラスのプライベートメンバーにアクセスできると規定されています。したがって、コンパイラはそのアクセスを許可します。一方、他の関数はそのようなアクセスを禁止されているので、コンパイラはそれについて文句を言います。

あなたの例では、メンバー関数からプライベートデータメンバーにアクセスしています。それは許可されているので、コードはコンパイルされます。つまり、コンパイラは文句を言いません。関数がインライン化された後、生成されたマシンコードの後半で何が起こるかは、まったく関係ありません。これですべてです。

于 2012-11-02T01:10:09.970 に答える
6

インラインの仕組みを誤解しています。コンパイラは、コードの実際のテキストではなく、コードのロジックをインライン化します。

クラスの外部からプライベートデータメンバーにアクセスできる理由を説明できますが、メンバー関数がインラインの場合、インラインは関数呼び出しを関数の内容に置き換えるだけですが、アクセスできますか?

関数の中身は関数の中身だから。インライン化されたからといって、関数であることをやめません。メンバー関数内からプライベート メンバー変数にアクセスできます。メンバー関数がインライン化されている場合、関数がインライン化されているため、そのコードはメンバー関数内に残っています。

于 2012-11-02T00:55:48.213 に答える
2

まず、インライン化するかどうかはコンパイラ次第です。多くの場合、最善の方法ではないと判断します。

第 2 に、インライン化する場合は、実際のテキストではなく、C++ ソース コードに記述されている動作の生成物であるコンパイル済みバイナリを使用してインライン化します。

于 2012-11-02T00:57:38.577 に答える
0

Morboは、インラインキーワードはそのようには機能しないと言います。

Morboによると、inlineキーワードは、この関数に関連するリンカー時のシンボルの競合は無視する必要があり、実装がクラスの宣言内にあるすべての関数は暗黙的にインラインであると述べています。

モルボは賢明です。アドレスを取ることを含むインラインのマイナーな技術的な追加の意味がある場合でも、Morboに耳を傾ける必要があります。

さらに深刻なことに、インラインでは、実装の定義をヘッダーファイルに入れましょう。したがって、実際にコードをインライン化することは、リンク時に発生する必要がないため(そして、ほとんどのC ++リンカーは怠惰すぎるため)簡単ですが、コードがインライン化されることはありません。

そして最後に、プライバシーは概念的なものであり、C++ランタイムによって強制されることはありません。これは、コンパイル時に、何かが範囲外であることを通知することによって強制されます。

于 2012-11-02T02:51:28.453 に答える