11

オブジェクト指向のコードを C で書くときは、通常、構造体の定義をパブリック関数と一緒にヘッダー ファイルに入れ、パブリック関数を別の .c ファイルに実装します。このクラスの「プライベート」なすべての関数に static キーワードを与え、.c ファイルにも実装します。パブリック関数は、同じクラスに属するプライベート関数を呼び出すことができます。プライベート関数は static キーワードのおかげで外部から呼び出すことができないため、GCC はこれらの関数の多くを最適化できます。それらはしばしばインライン化され、元の関数は出力オブジェクト ファイルから完全に削除されます。

ここで私の質問に: C++ クラスで同じことを行うにはどうすればよいですか?

ヘッダーファイルがあるとしましょう:

class A {
    int private_field;
    int private_function();
public:
    int public_function();
};

そして私の .cpp ファイル:

#include <iostream>
#include "A.h"

int A::private_function() {
    std::cin >> private_field;
    return private_field;
}

int A::public_function() {
    return private_function() + 4;
}

結果のオブジェクト ファイルでは、private_function は別のシンボルとして残され、public_function は private_function を呼び出します (インライン化されません)。private_function に内部リンケージを与えたいので、コンパイラーは C を使用する場合と同じ最適化を行うことができます。匿名の名前空間と静的で試しましたが、思い通りに動作させることができません。それを正しく行う方法、それは可能ですか? 私はGCCを使用しています。

4

1 に答える 1

14

クラス メンバーには内部リンケージがありません。標準は述べています(セクション9.3):

名前空間スコープ内のクラスのメンバー関数には、外部リンケージがあります。ローカル クラスのメンバー関数にはリンケージがありません。

したがって、内部リンケージを持つヘルパー関数を作成する場合は、非メンバーを使用する必要があります。

static int private_function(A* pThis);

class A
{
    int private_field;
    friend int private_function(A* pThis);
public:
    int public_function();
};

その後

#include <iostream>
#include "A.h"

static int private_function(A* pThis)
{
    std::cin >> pThis->private_field;
    return private_field;
}

int A::public_function() {
    return private_function(this) + 4;
}

標準 (セクション 11.3) の次の規則に注意してください。

フレンド宣言で最初に宣言された関数に外部リンケージがあります。それ以外の場合、関数は以前のリンクを保持します。

于 2012-12-29T23:28:42.643 に答える