はじめにC++インタフェースを書く:私は、従来のCのコードベースを多用しますC++ 11のアプリケーションを書いています。従来のコードで非常に一般的なパターンを構築し、基本的には、コンストラクタ/デストラクタであるよう動的に割り当てられたCの構造体
build_struct(LegacyStruct *L, int arg1, int arg2)
free_struct(LegacyStruct *L)
ような方法によって破壊されたいくつかのstruct LegacyStruct
の存在です。レガシーコードベースでの所有権のモデルは非常にunique_ptr
-esqueあるので、私は次のようにメモリ安全、RAII志向のラッパークラスでラップすることを目指して:
class Wrapper {
public:
Wrapper::Wraper() : handle() {}
Wrapper::Wrapper(int same_arg1, int same_arg2);
Wrapper::Wrapper(const Wrapper &W) = delete;
Wrapper::Wrapper(Wrapper &&W) : handle(std::move(W.handle)) {}
//copy operator= and move operator= analogously
private:
std::unique_ptr<LegacyStruct, custom_deleter> handle;
custom_deleter
通話this questionの線に沿ってfree_struct
、またはLegacyStruct
のstd::default_delete
の部分的な特殊化です。とにかく今のところこれほど良い、私はこれが共通のデザインパターンだと思うし、それは私のニーズによく合う。
私の質問:私はトラブル私は、フォーム再び
typedef struct LegacyNode {
int stack_allocated_data;
OtherStruct *heap_allocated_data;
LegacyNode *next;
} LegacyNode;
のリンクリスト型構造を扱っていただく場合には、このパターンを適応を持っています、レガシーコードベース内の所有権モデルがありますunique_ptr
-esque:リンクされたリストの唯一の所有権、すなわちそれを適切に解放する責任があります。同様に、対応するfree_node(LegacyNode *N)
関数があり、必要に応じてheap_allocated_data
を解放し、ノード自体を解放します。
でも状況はかなり異なります。
build_list(LegacyNode **L, int *count_p, int other_args){
LegacyNode *newnode;
//code allocating newnode and populating its fields
//...and then:
newcut->next = *L;
*L = newcut;
(*count_p)++;
}
のように見え、build_list
への呼び出しには、編集/明確化
int list_count = 0;
LegacyNode *L = (LegacyNode *) NULL;
build_list(&L, &list_count, 99);
のように見える機能があります:build_list
は、コードベースの静的、非エクスポートされた関数で、その私がおそらく数回build_list
を呼び出す他の関数を呼び出してアクセスしてください。
したがって、のような私は希望すなわち、ヘッドノードとリストの長さを格納ListWrap
クラスを作成し、コピーを持っている/上記Wrapper
と同一の演算子を移動させ、リスト自体を単独で所有権があり、それができますしかし、私の理解は、スマートポインタが、この場合、オプションではないということであるなど
、移動しますがコピーされないこと。レガシーノードへのスマートポインタとしてhead_node
を使用すると、&head_node.get()
をbuild_list
に渡す必要があります。これはスマートポインタの不変条件/所有権を破壊しますか?現状では
は、私のラッパークラスは、ヘッドノードへの生のポインタ、build_list
で使用するためにヘッドノードのアドレスを返すメソッドは、リストを反復処理がfree_node
を呼び出し、デストラクタ、および述語ベースerase
が含まれています特定の要素のみを削除する-typeメソッドもちろん
、リンクリストを変更し、クリアすると、CS-101レベルのものであるが、私はまだ数時間、それを書き込み、あらゆる場所にメモリリークを持つを無駄にするために管理!また、レガシーコードベースには、ほぼ同じ使用法を持つ他のリンクされたリスト構造がいくつかあるので、タイプとデリータに特化したクラステンプレートにすることができればと思っています。具体的な方法。
おかげ
'&head_node.get()'は有効ではありません。C++、あなたが見つかります。 – Yakk
@Yakk本当に、これは私が無邪気にやりたいことかもしれないと言うより良い言葉かもしれませんが、それはひどい考えであり、そのようには許されません! –