3

私は C++ で書かれた配布可能なライブラリを構築するのが初めてで、少し迷っています。ライブラリでユーザーに提供するすべての関数のラッパーを含む .cpp ファイルを作成し、パブリックとプライベートの 2 つの .h ファイルを作成しました。以下は私のヘッダーファイルのダミーの例です:

public.h:

class myclass
{
public:
    public_function();
private:
}

private.h:

class myclass
{
public:
    public_function();
private:
    anotherClass instanceofClass;
}

public_function()の実装では、コードで「instanceofClass」を使用することに注意してください。プライベート クラスを使用してコードを問題なくコンパイルし、パブリック ヘッダーとコンパイル済みライブラリを使用してライブラリをコンパイルし、外部プログラムとリンクすることができました。ただし、そのコードを実行すると、「instanceofClass」の適切な初期化の欠如に関係していると思われるセグメンテーション違反が発生します。

私は正しいことをしていますか?適切に初期化するために、実装内で「instanceofClass」をインスタンス化public_function()する必要がありますか、または代わりに他にすべきことはありますか?

どうもありがとう。

4

4 に答える 4

6

同じクラス「myclass」を2つの異なる方法で宣言することはできません。単一のクラス定義が必要です。実装のAPIを非表示にする場合は、「Pimpl」イディオムを使用します。したがって、パブリッククラスにはプライベートクラスへの単一のポインタがあります。例えば:

public.h

class myclass_private;
class myclass {
    private:
        myclass_private* pimpl; 
    public:
        myclass();
        void public_function();
};

public.cpp

myclass::myclass() {
    pimpl = new myclass_private;
}

void myclass::public_function() {
     pimpl->private_function();
}

private.h

class myclass_private {
    public:
        void private_function(); 
};
于 2012-11-18T00:00:42.230 に答える
1

public.hmyclassで定義されているメンバーにはメンバーがないため、サイズは1バイトです。private.hmyclassで定義されているのanotherClassは、をカプセル化するため、サイズanotherClassは何でもかまいません。この矛盾が問題の根本です。

ヘッダーを1つだけ持ち、ポインター(クラス定義を必要としない)を使用して、の実装を非表示にできるようにする必要がありanotherClassます。Joachimのpimplイディオムへのリンクを繰り返して詳しく説明します。

于 2012-11-18T00:00:00.490 に答える
1

クラスの定義は、異なる翻訳単位間で変わりません。これは、One Definition Rule の側面の 1 つです。プライベートな実装へのポインタを持つように公開クラスを定義するために必要なこと: Pimpl イディオム:

class Public {
public:
    ...
private:
     struct Impl;
     Impl* impl_;
};

struct Impl、実装ファイルでのみ定義されます。

于 2012-11-18T00:03:50.853 に答える
1

クラスには適切なコンストラクターがありません。つまり、コンパイラーはクラス定義の内容に基づいてデフォルトのコンストラクターを提供します。その定義がすべてのコードで一貫していない場合、どこでも同じように初期化されず、一部のデータが欠落する可能性があります。

の実装の詳細を非表示にしたい場合はinstanceofClass、ヘッダーで前方宣言を行い (提供しているプラ​​イベート ヘッダーは正しく、パブリック ヘッダーとして使用できます)、コードのどこかに実装を提供します。

于 2012-11-18T00:10:25.480 に答える