2


2

私は最近傍のクエリを実行するコードに取り組んでいます。 ユーザーが検索でデータを照会する方法の根底にある2つの簡単なアイデアがあります。

  • 最近接N個は、空間内の特定の点を指します。

  • 与えられた距離内のすべての点

私のコードでは、PointはPointListに入れられ、PointListは検索で見つかった点を追跡する役割を果たします。

今のところ私のPointListオブジェクトは一つのコンストラクタを持っています:

PointList(unsigned int maxvals); //#1

私が追加したい次の2つのコンストラクタはこれらです:

PointList(float maxdist); //#2 PointList(unsigned int maxvals、float maxdist); //#3

私の質問は、ユーザーとCコンパイラがPointListに適切なコンストラクタを生成し、コンストラクタ1と2を区別するようにするにはどうすればよいのですか。 #3を実装して、maxvalsとmaxdistに任意の大きな値を定義する定数を提供する必要がありますか? もう1つの選択肢は、ポイントをリストに追加するためのロジックを管理する軽量オブジェクトの別のシステムを作成することですが、そのような単純なアイデアにはやり過ぎるようです。

私は本当にこれを私のユーザーにとって透明にしようとしています。彼らはたいてい正式な教育の恩恵なしにCを時々学んだ科学者です。 ありがとうございます。

7 Answer


6


なぜコンストラクタの代わりにファクトリメソッドを使わないのですか? ファクトリメソッドにはカスタマイズ可能な名前という利点があります。

static PointList createNearestValues(unsigned int maxvals){} static PointList createByDistance(float maxdist){}


5


整数型のオーバーロード解決は2つのカテゴリで発生します。

  • プロモーション:これは、「+ int 」よりも小さい型から ` int `がソース型のすべての値を保存できるかどうかに応じて、 ` int `または ` unsigned int +`。

  • 変換:これは、任意の整数型から別の整数型への変換です 整数型。

同様に、浮動小数点型への変換は2つのカテゴリで行われます

  • プロモーション:これは、「+ float 」から「 double +」への変換です

  • 変換:これは、任意の浮動小数点型からへの変換です 別の浮動小数点型

そして整数から浮動または逆への変換があります。 これはプロモーションではなくコンバージョンとしてランク付けされます。 プロモーションはコンバージョンよりもランクが高く、プロモーションのみが必要な場合はその場合が優先されます。 したがって、次のコンストラクタを使うことができます。

PointList( int maxVals );
PointList( unsigned int maxVals );
PointList( long maxVals );
PointList( unsigned long maxVals );

PointList( double maxDist );
PointList( long double maxDist );

どんな整数型でも、これはコンストラクタの最初のグループを選択するべきです。 そしてどんな浮動小数点型のためにも、これはコンストラクタの2番目のグループを選択するべきです。 元の2つのコンストラクタは、たとえば、+ int を渡すと、 float と unsigned int +のあいまいさを簡単に引き起こす可能性があります。 もう一方の2つの引数を持つコンストラクタの場合は、必要に応じて解決策を取り入れることができます。

'' '' '

とは言っても、私はファクトリ関数も使用するでしょう。なぜなら、パラメータの意味を型で決定するのは非常に壊れやすいからです。 ほとんどの人は、次の結果が等しいと期待するでしょう

PointList p(floor(1.5));
PointList u((int)1.5);

しかし、それは別の状況になるでしょう。


2


http://www.ddj.com/cpp/184401633[true typedef]の使用を検討してください。 それはあなたのクライアントコード側のもう少しの努力ですが、あなたは正当性を保証されています。


1


最初のPointList(10)と2番目のPointList(10f)を呼び出します。

2番目には、10.0も使えます。


1


#1と#2のコンストラクタが存在する場合、挿入した値がfloatまたはintで、変換が行われない場合は、正しいコンストラクタが呼び出されます。 だからあなたが明示的に呼び出すためにあなたが使用する数のタイプを明示的にすることを確実にするだけです。 1fと1)。 コンストラクタ#3は、実際には必要ではなく、コードのユーザを混乱させるだけなので、あまり選択肢にはなりません。 どちらかの数値にデフォルト値が必要な場合は使用できます

PointList(int max、float max = VALUE)

そして

PointList(浮動小数点最大、整数最大= VALUE)

繰り返しますが、これはコードの可読性の点でコードよりも害が大きいようです。


0


私は間違いなく* explicit *コンストラクタを使用します。 この例では、符号なし整数は暗黙的に変換されません。

クラスA {public:明示的A(float f){}明示的A(int i){}};

void test(){unsigned int uinteger(0); A 1(整数)。 //失敗、暗黙の変換は許可されません

a2((float)整数); // OK、明示的な変換

float f(0.0); A a3(f)。 //OK

int整数(0)。 a a 4(整数)。 //OK }

エラーメッセージは理解するのに十分簡単です:

: error C2668: 'A::A' : ambiguous call to overloaded function
: could be 'A::A(int)'
: or       'A::A(float)'