簡體   English   中英

在C ++中管理隱式類型轉換

[英]Managing Implicit Type Conversion in C++

我正在研究做最近鄰查詢的代碼。 有兩個簡單的想法可以作為用戶查詢搜索中數據的基礎:

  • 最近的N指向空間中的給定點。
  • 給定距離內的所有點。

在我的代碼中,Points被放入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的任意大值的常量嗎? 另一個替代方案可能是編寫另一個輕量級對象系統來管理將Points添加到列表中的邏輯,但這對於這樣一個簡單的想法來說就像是有點過分。

我真的試圖讓我的用戶透明,這些用戶大多是在沒有正規教育的情況下學習過C ++的科學家。 謝謝!

為什么不使用工廠方法而不是構造函數? 工廠方法具有可自定義名稱的優點。


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

整數類型的重載分辨率發生在兩個類別上,可以非常粗略地概括為

  • 升級:這是從小於int類型到intunsigned int ,具體取決於int是否可以存儲源類型的所有值。
  • 轉換:這是從任何整數類型到另一個整數類型的轉換。

類似地,浮點類型的轉換發生在兩個類別上

  • 促銷:這是從floatdouble的轉換
  • 轉換:這是從任何浮點類型到另一個浮點類型的轉換

並且存在從整數到浮動或返回的轉換。 這被歸類為轉化,而不是促銷。 促銷的排名優於轉化,並且只需要促銷,該情況將是首選。 因此,您可以使用以下構造函數

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

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

對於任何整數類型,這應該選擇第一組構造函數。 對於任何浮點類型,這應該選擇第二組構造函數。 例如,如果傳遞一個int ,那么原始的兩個構造函數很容易導致floatunsigned int之間的歧義。 對於另一個,兩個參數構造函數,如果需要,可以使用您的解決方案。


也就是說,我也會使用工廠函數,因為我認為決定參數含義的類型是非常脆弱的。 大多數人都希望以下結果相等

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

但這會導致不同的事態。

考慮使用true typedef 您的客戶端代碼需要付出更多努力,但保證您的正確性。

為第一個調用PointList(10),為第二個調用PointList(10f)。

對於第二個,您也可以使用10.0。

如果構造函數#1和#2存在,如果您插入的值是float或int,則將調用正確的構造函數,並且不應進行任何轉換。 因此,只需確保您使用顯式調用的數字類型(即1f和1)。 構造函數#3似乎不是一個選項,因為它不是真正必要的,只會混淆代碼的用戶。 如果您需要任何一個號碼的默認值,您可以使用

PointList(int max, float max=VALUE)

PointList(float max, int max=VALUE)

再說一遍:在代碼可讀性方面,這似乎比代碼更有害。

這要求對過載分辨率進行良好的閱讀。

我肯定會使用顯式構造函數。 在示例中,無符號整數不會隱式轉換。

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)'

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM