题
我正在代码最近邻的查询。有两个简单的想法背后的用户如何可查询的数据搜索:
- 最近N点的给定点空间。
- 所有各点在一定的距离。
在我的代码,分放入一个PointList,PointList是一个容器的有工作的跟踪点,已经发现在的搜索。
现在我PointList对象有一个构造:
PointList( unsigned int maxvals ); // #1
接下来的两个构造,我想补充的是这些:
PointList( float maxdist ); // #2
PointList( unsigned int maxvals, float maxdist ); // #3
我的问题是:我怎么确保我的用户和用C++编译器将产生的权利 构造的PointList和区分造1和2?我是不是应该实现#3和提供常数,界定任意大 值maxvals和maxdist?另一个替代的可能写另一个系统的轻对象的管理逻辑,用于添加点清单,但是这感觉就像矫枉过正,对于这样一个简单的想法。
我真的很想让这种透明的对于我的用户,他们主要是科学家们已经学会了用C++有时没有正式的教育。谢谢!
解决方案
载的决议对于整数类型发生在两个类别,其中可以非常粗略地总结了
- 促进:这是转换的类型比较小
int
要int
或unsigned int
, 取决于是否int
可存储的所有价值观的源类型。 - 转换:这是一个转换从整数的任何类型的另一整类型。
类似的,转用于浮点类型发生在两个类别
- 促进:这是一个转换
float
要double
- 转换:这是转换的任何浮点类型的另一个浮点类型
并且有是一个转换从整数的浮动或返回。这是第一个转换,而不是一个促进。一个促进被排优于转换,其中只有一种促进是必要的,这种情况下,将优先。因此,你可以用下面的构造
PointList( int maxVals );
PointList( unsigned int maxVals );
PointList( long maxVals );
PointList( unsigned long maxVals );
PointList( double maxDist );
PointList( long double maxDist );
对于任何整数类型,这应该选择第一组的构造。和任何浮点类型,这应该选择第二组的构造方法。你原来的两个构造可以很容易地导致一种模糊性之间 float
和 unsigned int
, 如果你通过 int
, 例。对其他两个参数的构造,你可以用你的解决方案,如果你想要的。
这就是说,我会用一家工厂的功能,因为的类型决定意义的参数是相当脆弱的,我认为。大多数人都会希望以下结果的平等
PointList p(floor(1.5));
PointList u((int)1.5);
但是,这将导致在不同国家的事务。
其他提示
为什么不使用工厂的方法,而不是造?工厂的方法具有优点的定的名称。
static PointList createNearestValues(unsigned int maxvals) {}
static PointList createByDistance(float maxdist) {}
考虑使用 真typedef.这是一个小小的更多努力的一部分你的客户代码,但是你保证的正确性。
呼叫PointList(10)对于第一和PointList(10)第二。
第二,你也可以使用10.0.
如果造1和2是本正确的构造将被称为如果你的价值的插入的浮动或int并没有转换应该采取的地方。所以只要保证你做出的种类型的号码,你用它来调用明确的(即,1f和1).构造#3似乎并不是一个选项,因为它是不是真的有必要,只会混淆用户的代码。如果你需要的默认值或数量可以使用
PointList(int max, float max=VALUE)
和
PointList(float max, int max=VALUE)
再次:这似乎做更大的伤害,然后码在条码阅读。
这是一个很好的阅读 载的决议.
我肯定会使用 明确 构造方法。在例的unsigned integer不转换隐含.
class A
{
public:
explicit A(float f){}
explicit A(int i){}
};
void test(){
unsigned int uinteger(0);
A a1(uinteger); //Fails, does not allow implicit conversions
A a2((float)uinteger); //OK, explicit conversion
float f(0.0);
A a3(f); //OK
int integer(0);
A a4(integer); //OK
}
错误信息是足够容易理解:
: error C2668: 'A::A' : ambiguous call to overloaded function
: could be 'A::A(int)'
: or 'A::A(float)'