1

このように不完全な構造体を使用する C のコードがあります (簡略化された例):

何か.h

struct something;

struct something *new_something();
int work_a(struct something *something);
int work_b(struct something *something, const char *str);
void free_something(struct something *something);

somecode.c

int some_function()
{
    struct something *something;
    int x;

    something = new_something();
    x = work_a(something);
    free_something(something);
    return x;
}

私は基本的にここで C++ をやっているのですが、 C++ で書いてみませんか。問題は (私は C++ の初心者です)、どうすれば C++ で同じことを達成できますか? 不完全なクラスのメンバー関数を追加宣言しようとすると、

error: incomplete type 'something' named in nested name specifier

クランから。ヘッダーに完全なクラスを記述すると、データを隠すという点がすべて失われ、クラスのプライベート変数を変更すると、「something.h」を含むすべてのファイルが強制的に再コンパイルされますが、ここでは必要ないと思います。この構造体/クラスのサイズを知るために「something.h」を使用するファイルは必要ありません。通常はポインターだけで問題ありません。私はそれが次のようになるべきだと思った:

 class Something;

 Something::Something();
 Something::~Something();
 int Something::work_a(int x);

このようにして、C で書いたのと同じことを、より短く、さらにきれいに書くことができました。この致命的な C コーダーを啓蒙したい C++ コーダーはいますか?

4

3 に答える 3

2

この記事を見てみましょう: C++ で実装の詳細を非表示にします。見ている方向に向けられるはずです。目標を達成するために継承が使用されていることに注意してください。また、C++ では、構造体はすべてのメンバーがパブリック アクセスを持つクラスであることも理解してください (関数、コンストラクター、およびデストラクターを含む)。少なくとも、インターフェイスをクラスとして宣言し、cpp ファイル (別のヘッダー ファイルではない) 内の現在非表示のクラス実装で公開されているものから継承する必要があります。

Pimpl 設計パターンについては、スタック オーバーフローの記事: pimpl idiom vs. bridge design patternを参照してください。それも役立つはずです。

于 2014-03-19T01:37:40.123 に答える
1

これを実現する 1 つの方法は、実装のみが知っているプラ​​イベート構造体/クラスへのポインターを持つ Pimpl デザイン パターンを使用することです。プライベート関数はポインターを使用し、理論的にはほとんどインライン化できます。

于 2014-03-19T01:25:19.647 に答える
0

new ステートメントでメモリを割り当てる場合、コンパイラは割り当てるデータ領域の量を知る必要があります。newを使用してSomethingインスタンスを作成する前に、Somethingのデータサイズがコンパイラによって確認されています。

このようなものをSomething.hで使用します

class Something {
public:
 Something();

private:
 struct HiddenData;
 HiddenData* m_pHidden;
};

このようなものをSomething.cppで使用します

struct Something::HiddenData {
int a;
int b;

};

Something::Something() : m_pHidden(new HiddenData()) {
 m_pHidden->a = 1;
}
于 2014-03-19T01:50:12.683 に答える