2013-05-07 2 views
13

オブジェクトのスライスは、派生クラスのオブジェクトをその基本クラスのオブジェクトに割り当てまたはコピーし、プロセスの派生部分を失うと発生します。オブジェクトのスライスは今まで有用でしたか?

ここでは、What is the slicing problem in C++?について詳しく説明しました。

(私自身、私は問題、言語の値のセマンティクスのではなく自然な結果としてそれを見ることはありませんが、それはこの質問のポイントではありません。)

私は不思議どのようなものです:ありますあなたがそれを意図的に使用する状況はこれまでありませんでしたか?それは "仕事のための正しいツール"ですsitutation?

+1

可能な重複: http://stackoverflow.com/questions/2389125/object-slicing-is-it-advantage – shivakumar

+0

@shivakumarおかげで、素敵な発見。しかし、答えの例が構成されています。誰かが実世界の例を考え出すことを望んだ。 – jrok

答えて

5

確かに、それはおそらく依存関係を落とすために、クラスの派生部分を削除したいときに便利です。

たとえば、各ベースが派生型に属し、派生型のそれぞれに依存性の注入によって実現されるさまざまな依存性があるオブジェクトシステムのセットアップがあるとします。そのベースの実際の派生型に完全に新しい依存関係を割り当てることができますが、ベースのクローンを作成したいかもしれません。

これは、多くの種類のコライダーが存在するゲームエンジンに似ています。各コライダーは、さまざまな方法で基本インターフェースのようなオブジェクトから派生しています。私たちは、コライダーをクローンして(ベースから)その位置とスケールを取得したいが、このベースの上にまったく異なる派生実装を配置したいと思う。 「オブジェクトのスライシング」は、これを実現する簡単な方法です。

実際にコンポーネントまたは集約オブジェクトの編成は、オブジェクトのスライスよりもはるかに理にかなっていますが、ほとんど同じ考えです。

+0

概念的には、任意の型の継承関連の置換可能性は、一般に、正確に1つの特定の変更可能な間接化の意味で意味があるようです。 Javaと.NETアレイ代替以外は単独で、間接参照に適用される( 'base'を参照するための' derived'代用を参照するが、例えば 'リストが' 'リスト'の代わりない)と仮定私は、主なスライシング「問題」は、直接的に代入可能な型は、可変参照の間接置換を許さないという事実に由来すると考えています。 – supercat

0

いくつかのSTLの実装は、実際にアルゴリズムを実装するオブジェクトのスライスを使用します。 例えば、iterator_tags を使用して、簡単にstd::advanceが最も効率的なアルゴリズムを使用することができます。それ以外の場合はあいまいな

あなたは明確にすることができ、独自の小さなクラス階層を使用して
namespace std { 

template <class I> 
void advance_impl(I& it, int n, input_iterator_tag) { 
    for (; n > 0; --n) 
     ++it; 
} 

// Forward Iterators use the same implementation as Input Iterators... 

// TODO: 
// Add bidirectional_iterator_tag implementation... 

template <class I> 
void advance_impl(I& it, int n, random_access_iterator_tag) { 
    it += n; 
} 

template <class I> 
void advance(I& it, int n) { 
    advance_impl(it, n, typename iterator_traits<I>::iterator_category()); 
} 

} // std 

を関数のオーバーロード。例えば。オブジェクトをstd::stringに変換するには、オブジェクトメンバ関数to_string()(存在する場合)を使用するか、そうでない場合はoperator<<を使用します。

struct R2 {};  // rank 2 
struct R1 : R2 {}; // rank 1 

// C++11. 
// Use some type traits and enable_if in C++03. 
template <class T> 
auto ToString(R1, T const& t) -> decltype(t.to_string()) { 
    return t.to_string(); 
} 

template <class T> 
std::string ToString(R2, T const& t) { 
    std::ostringstream s; 
    s << t; 
    return s.str(); 
} 

template <class T> 
std::string ToString(T const& t) { 
    return ToString(R1(), t); 
} 
関連する問題