2013-03-18 15 views
5

私のコードで3D点と2D点を明確に区別したいと思います。明らかな解決策は、別々のクラスを持つことです。暗黙の変換を禁止する方法を教えてください。

一方、z = 0から2次元の点を持つ3D点からの変換はかなり一般的です。したがって、共通の基底クラスを使用したいので、それらの変換をメモリ内でその場で行うことができます。 型を明確に区別するために、その基本クラスへの暗黙的な変換を禁止したいと思います。それは実践ですか?

または、このような類似の機能を持つ異なるタイプを作成するための別の方法がありますか?

+3

hm、ここで見てみたいです(ヒント: 'explicit'):-) http://stackoverflow.com/questions/121162/what-does-the-explicit-keyword-in-c-mean – Najzero

+0

「メモリ内のインプレース」変換の例を教えてください。先験的に、私は、2Dの3Dポイント間の任意の公開継承は不自然で混乱しているように思う。 – juanchopanza

+0

共通の基底クラスが、3Dポイントを2Dポイントに変換する方法を、どうにかすることはできません。 「B」が「2Dpoint」と「3Dpoint」の両方の基底であり、「x」と「y」の座標が「B」に格納されているとします。さらに、 '3Dpoint'のインスタンスがあり、何もコピーせずに' 2Dpoint'のインスタンスが必要であるとします。次は何? –

答えて

1

3Dベクターの2次元部分に何もコピーせずにアクセスしたいのであれば、本当に1つのみの解決策があります。

class Vector2d { ... }; 
class Vector3d { 
    Vector2d part2d; 
    double z; 
public: 
    Vector2d& as2d() { return part2d; } 
}; 

どれ継承ベースのペテンは悪いデザイン、未定義の動作、またはその両方につながる可能性が非常に高いです。

+0

これらのポイントで動作する機能に応じて、プライベートメンバーまたは保護されたメンバーにアクセスできることは有益かもしれませんが、あなたは正しいです。そうでない場合は、あなたの解決策を優先するべきです。 – Sarien

2

これはあなたの質問に答えることはできませんが、問題を解決するために、要求されたときに2Dポイントを返す3Dクラスのメソッドを作成できます。

2

あなたは個人的に子クラスを派生されることがあります。このアプローチの

class PointBase { 
    // ... 
}; 

class Point2D : private PointBase { 
    // ... 
}; 

class Point3D : private PointBase { 
    // ... 
}; 

副作用もPointBaseの任意のパブリックメンバーは外部からアクセスできないだろうということなので、サブクラスは、明示的にアクセスできるようしなければなりません、プロキシメソッドを提供するか、キーワードusingで指定します。だからこそ、私はPointBaseの共通ロジックがかなりあり、それが単一の場所で実装されていれば、前述の欠点より多くの利益がもたらされる場合に限り、この方法になります。

+0

確かに、私はちょうど古い学校なので、しばしば新しいC++の機能を忘れてしまいます。しかし、 'using'はタイプミスが少ないにもかかわらず、開発者は' PointBase'から関連するメソッドにアクセスできるようにする必要があります。 – mity

+0

それを含む答えを編集しました。 – mity

1

あなたのポイントはベクトルとして保存されている場合、あなたは次元数を指定しますintパラメータを持つテンプレートクラスとして、あなたの3Dと2Dのポイントクラスを定義することができます。

template<int dimensions> class Point { 
    vector<int> coords; 
    Point() : coords(dimensions) {} 
    .... 
    template<int other_dimensions> convertToPoint() const 
    { 
     // Handle different options here like: 
     // dimensions > other_dimensions 
     // dimensions < other_dimensions 
     // et cetera 
    } 
}; 

をポイントクラスをインスタンス化します。

typedef Point<2> Point2D; 
typedef Point<3> Point3D; 
Point2D pt = Point3D(1, 2, 3).convertToPoint<2>(); // Point2D(1, 2); 
Point3D pt = Point2D(4, 5).convertToPoint<2>(); // Point3D(4, 5, 0); 

このようにすれば、ロジックは同じだが完全に異なるタイプと簡単なコンバージョンが得られます。言い換えれば、の1つだけをクラスと2つの別々のクラスの代わりに定義する必要があります。

関連する問題