簡體   English   中英

在C ++中鍵入別名

[英]Type aliases in C++

我有一個Point類和一個Rect類。 我想為Rect有兩個構造函數:一個帶有Point和一個尺寸(寬度,高度)的構造函數,一個帶有兩個Point(左上,右下)的構造函數。 現在事實證明Point也可以看作是一個維度,因此與其創建Dimension類,不如我想使用Point ,基本上是這樣的:

class Point{...};
typedef Dimension Point;

class Rect{
    public:
        Rect(Point, Point);
        Rect(Point, Dimension);
}

所以問題是:編譯器是否會在PointDimension之間產生區別? 我嘗試過,消息ist“重載Rect(Point,Point)的調用是模棱兩可的”。

我該怎么辦? 最好沒有繼承:)

編輯

我現在了解到編譯器是相同的。 但是還有另一種需要的情況。

我有一個要點。 坐標可以在笛卡爾系統(x,y)或GPS坐標(lon,lat)中。 對我來說,調用組件x0x1所以我只想使用一個類。

現在我要計算兩點之間的距離,我的想法如下:

typedef PointLonLat Point;
typedef PointXY Point;

double distance(PointLonLat, PointLonLat);
double distance(PointXY, PointXY);

PointLonLat p1(10, 10);
PointLonLat p2(11, 11);

double dist = distance(p1, p2); // the correct implementation is used

我知道它不是那樣工作的。 但是,答案是否還會是“兩堂課”?

所有類型定義對於編譯器都是相同的。

你可以這樣做:

//class template to be used to generate different class types!
template<int>
class Type{ /*...*/ };

//instantiate different class types, each with different template argument
typedef Type<0> Point;
typedef Type<1> Dimension;
typedef Type<2> Size;

class Rect{
    public:
        Rect(Point, Point);
        Rect(Point, Dimension); //its a different constructor!
};

使用這種方法,您可以在類模板Type創建不同的類型。


除了整數文字,您可以將命名枚舉用作:

enum TypeArg
{
    PointArg,
    DimensionArg,
    SizeArg
};

template<TypeArg>
class Type{ /*...*/ };

typedef Type<PointArg>     Point;
typedef Type<DimensionArg> Dimension;
typedef Type<SizeArg>      Size;

甚至最好將空類用作:

//empty classes
struct PointArg{};
struct DimensionArg{};
struct SizeArg{};

template<typename T>
class Type{ /*...*/ };

typedef Type<PointArg>     Point;
typedef Type<DimensionArg> Dimension;
typedef Type<SizeArg>      Size;

許多C ++庫(例如Boost)都采用了最后一種方法。

您應該使Dimension為其他類型。 是的,可以使用Point來指定尺寸,但這並不意味着使用相同的類型是有意義的。

編譯器在PointDimension之間沒有區別。

您必須為Dimension創建另一個類。 只是提示,您可以使用wh代替xy作為其成員。

如果pointdimension行為不同,則您的typedef是邏輯錯誤。 如果他們這樣做,則您不需要兩個構造函數。


回應您的編輯

對於您提供的示例,您擁有的兩個類存儲相同數量的數據,但行為不同。 這與std::size_tvoid*完全不同-它們對於底層硬件來說都是相同的位數,但是語言的類型系統賦予它們完全不同的含義。

您的示例可以通過使用兩個不同的類或通過使用模板類來避免重復來解決,例如:

enum CoordinateSystem {
  Geographic,
  Cartesian
};

template<CoordinateSystem C>
struct Point {
  double x,y;
};

double distance(Point<Cartesian>, Point<Cartesian>);
double distance(Point<Geographic>, Point<Geographic>);

一種快速的解決方案是,您可以有一個構造函數,並弄清楚邏輯內部提供的類

盡管Dimension和Point是相似的,因為它們都可以實現為一對數字,但是它們的行為並不相同,例如Dimension可能具有height()和width()之類的成員函數,而Point可能具有x()和Y()。 因此,您不應該使它們相同,但是每個類具有不同的類。

您可以嘗試使Dimension從Point繼承,而不是成為typedef:
class Dimension : public Point {}
同樣,將對象類型作為副本傳遞效率很低。 而是將它們作為常量引用傳遞。 這具有允許編譯器為那些類型生成多態代碼的額外好處。

暫無
暫無

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

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