2014-08-28 116 views
8

我正在尋找在GIS中使用的一組點類型,它們是2D(xy),3D(xyz或xym)或4D(xyzm)。 M座標是度量座標,其他座標應該是顯而易見的。但是,我似乎無法弄清楚如何使PointZM類共享Point類中的xy成員。這裏是我的代碼:共享繼承C++中的多態性

#include <iostream> 

class Point { 
    public: 
    double x, y; 
    Point (double xNew, double yNew) : x(xNew), y(yNew) {}; 
}; 

class PointZ : public Point { 
    public: 
    double z; 
    PointZ (double xNew, double yNew, double zNew) : 
     Point(xNew, yNew), z(zNew) {}; 
}; 

class PointM : public Point { 
    public: 
    double m; 
    PointM (double xNew, double yNew, double mNew) : 
     Point(xNew, yNew), m(mNew) {}; 
}; 

class PointZM : public PointZ, public PointM { 
    public: 
     PointZM (double xNew, double yNew, double zNew, double mNew) : 
      PointZ(xNew, yNew, zNew), PointM(xNew, yNew, mNew) {}; 
}; 

int main() { 
    Point p (1, 2); 
    PointZ pZ (1, 2, 3); 
    PointM pM (1, 2, 4); 
    PointZM pZM (1, 2, 3, 4); 
    std::cout << "Point: " << sizeof(p) << std::endl; 
    std::cout << "PointZ: " << sizeof(pZ) << std::endl; 
    std::cout << "PointM: " << sizeof(pM) << std::endl; 
    std::cout << "PointZM: " << sizeof(pZM) << std::endl; 
} 

打印每個類的四個實例的大小:

Point: 16 
PointZ: 24 
PointM: 24 
PointZM: 48 

我期待最後PointZM爲32個字節,因爲它應該有xyzm成員。我怎麼能得到兩個繼承類PointZPointM分享他們繼承的Point成員?有兩種方法可以獲得兩個類的聯合嗎?我是這個主題的C++新手。

爲什麼要打擾繼承的動機是不明顯的簡單點幾何。但是,如果進一步開發不同的幾何類型,如LineString(2D),LineStringZ(3D),LineStringM(3D)或LineStringZM(4D),則它們將具有如果存在Z維度則會不同的幾何類型。只有存在Z維度時,長度方法纔會有不同的計算方法,我不想將其加倍到LineStringZLineStringZM類別。

+4

'PointZM'有兩個'Point'實例。無論如何,繼承在這裏看起來不正確。我不會說4D點*是-A * 2D點。 – juanchopanza 2014-08-28 06:44:00

+3

查看虛擬基類;但在這裏誠實地繼承可能不是一個好主意。 – 2014-08-28 06:44:29

+0

這裏的課堂模板會更好嗎?再次,我是這個領域的新手。 – user3985527 2014-08-28 06:45:08

回答

4

直接回答你的問題是使用virtual inheritance。這將使PointZM只包含一個點,而不是兩個。您稍後可能會認爲這不值得複雜,而是分別實施PointZ,PointM和PointZM,但這取決於您。

在我的系統上,虛擬繼承爲每個虛擬派生類型增加了8個字節,並且PointZM保持相同的大小,因爲它包含的額外Point的16個字節被刪除,但我們現在有兩個額外的指針存儲在虛擬基地類。那麼尺寸是這樣的:

Point: 16 
PointZ: 32 
PointM: 32 
PointZM: 48 
+0

[意見]儘管這是正確的,但在這種情況下,我會避免虛擬繼承(以及虛擬任何東西)。可能會有大量的這些,在這種情況下,每個字節都是很重要的。正如我在主要問題的評論中寫到的,我會去單獨的POD。 [/評論] – 2014-08-28 07:09:47

+0

@Laethnes:如果需要高性能,我會和你一樣。 – 2014-08-28 07:13:29

5

有2D幾何,3D幾何和4D幾何。 3D幾何不是2D幾何的精煉實例,它是一個完全不同的野獸。同樣,4D幾何不是三維幾何的特例。

公有繼承意在表達is-a的關係。不同尺寸幾何之間沒有這種關係。

非公共繼承可用於代碼共享,但不清楚可在2D,3D和4D情況下共享哪些代碼。

但是,所有這些幾何形狀都是通用N尺寸幾何形狀的情況,N是參數。用類模板進行建模是很自然的。

template <size_t N> 
    class Point 
    { 
     std::array<double, N> coord; 
     // ... rest of the code ... 
    };