データ構造が「侵入的」であるとはどういう意味ですか?


120

リストやスタックなどのデータ構造を説明するために侵入型という用語を使用したことがありますが、それはどういう意味ですか?

侵入型データ構造のコード例を教えてください。侵入型データ構造との違いはありますか?

また、なぜそれを邪魔にならない(または邪魔にならない)のですか?メリットは何ですか?欠点は何ですか?

回答:


107

侵入型データ構造は、それらを格納するために格納しようとしている要素の助けを必要とするものです。

言い換えましょう。そのデータ構造に何かを入れると、その「何か」は、何らかの形でそのデータ構造にあるという事実を認識します。要素をデータ構造に追加すると、要素が変更されます。

たとえば、各ノードが左右のサブツリーへの参照とそのノードの要素値への参照を持つ非侵入型バイナリツリーを構築できます。

または、それらのサブツリーへの参照が値自体に埋め込まれている、煩わしいものを構築することもできます。

煩わしいデータ構造の例は、変更可能な要素の順序付きリストです。要素が変更された場合、リストを並べ替える必要があるため、リストオブジェクトは要素のプライバシーを侵害して要素の協力を得る必要があります。すなわち。要素は、それが含まれているリストを認識し、変更を通知する必要があります。

ORMシステムは通常、侵入型のデータ構造を中心に展開し、オブジェクトの大きなリストでの反復を最小限に抑えます。たとえば、データベース内のすべての従業員のリストを取得し、そのうちの1人の名前を変更し、それをデータベースに保存したい場合、従業員オブジェクトの変更時に従業員の侵入リストに通知されます。オブジェクトはそれがどのリストにあるかを知っています。

邪魔にならないリストは知らされず、何が変わったのか、それ自体がどのように変わったのかを理解する必要があります。


8
私はまだ例と長所と短所を見たいですが、これは良い紹介です。
Rudiger、2011

コードをポストするのではなく、STLは非侵入型であると言いますが、Boost.Intrusiveは(明らかに)侵入型です。
ストーンメタル

1
侵入型の長所:データをそのまま使用できる内部構造にコピーする必要はありません。短所:データを格納するコンテナーをサポートするには、データのカプセル化を解除する必要があります。データを複数のコンテナーに配置する必要がある場合は、トリッキーになる可能性があります。非侵入型コンテナー長所:コンテナーのデータを変更する必要がなく、カプセル化が向上します。短所:データを内部ノード構造にコピーする必要があります。
ストーンメタル

3
boost.org/doc/libs/1_45_0/doc/html/intrusive.htmlには、長所と短所の例と適切な説明があります。
Tony Delroy、


22

侵入型コンテナでは、データ自体がコンテナに必要な情報を格納する責任があります。つまり、データタイプは格納方法に応じて特殊化する必要がある一方で、データは格納方法を "認識"しているため、少しだけ最適化できるということです。

非侵入型:

template<typename T>
class LinkedList
{
  struct ListItem
  {
    T Value;
    ListItem* Prev;
    ListItem* Next;
  };

  ListItem* FirstItem;
  ListItem* LastItem;

  [...]
  ListItem* append(T&& val)
  {
    LastItem = LastItem.Next = new ListItem{val, LastItem, nullptr};
  };
};

LinkedList<int> IntList;

煩わしい:

template<typename T>
class LinkedList
{
  T* FirstItem;
  T* LastItem;

  [...]
  T* append(T&& val)
  {
    T* newValue = new T(val);
    newValue.Next = nullptr;
    newValue.Prev = LastItem;
    LastItem.Next = newValue;
    LastItem = newValue;
  };
};

struct IntListItem
{
  int Value;
  IntListItem* Prev;
  IntListItem* Next;
};

LinkedList<IntListItem> IntList;

個人的には、透明性のために押し付けがましいデザインを好みます。


侵入型コンテナ内にいることはオブジェクトに対して透過的ではないので、その最後の行は「透過的」という単語の使用法のために奇妙です。
そり

@ArtB最終的なアプリケーションでデータがどのように使用されるかを明確に伝えることができます。非侵入型データの場合、通常はコンテナーを掘り下げる必要がありますが、侵入型データの場合は、データの構造のみからそれを表示します。
API-Beast

1
まあ、私は、透明性の「透明性」の使用法は、どの観点からも限定されるべきだと思います。私の経験では、「透過的」は、データの処理方法がドメインから見えないことを示すためによく使用されます(つまり、ドメインモデリングは純粋です)。この言葉が両方の意味で使われているのなら、何か価値があるのでしょうか。
そり

2
@ArtBああ!トランスペアレントには、特別なコンピュータサイエンスの意味があります。私にとって透明とは、cs以外のコンテキストで使用されている用語のように、内部を見ることができることを意味します(たとえば、「ビューを妨げない」)。
API-Beast
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.