我對 OOP 有點陌生,所以這個問題感覺有點奇怪,但我想知道在這種情況下我應該做什么
假設我有一個 Tup4 類,它只包含 4 個雙打,以及兩個擴展 Tup4 的類 Point4 和 Vec4。現在,檢查 Tup4 中的相等性只是比較每個元組中的所有 4 個雙精度值是否(大約)相等。這在擴展它的兩個類中都成立。但是,在 Tup4 中定義相等函式是沒有意義的,因為這樣我就可以檢查 Point 和 Vector 之間的相等性,這沒有多大意義。所以我不能在Tup4中定義一個虛擬的equals方法,那我該怎么辦?兩種情況下的代碼完全相同,唯一的區別是函式的型別。所以我想知道我是否可以避免使用兩種方法
bool equals(Point4 p);
bool equals(Vec4 v);
他們都做同樣的事情,但在不同的類中定義
uj5u.com熱心網友回復:
看起來您已經接受了答案。但這是我不走模板路線的建議:
在你的 Tup4 類中定義一個相等的方法,但讓它受到保護:
class Tup4
{
public:
double a, b, c, d;
protected:
bool EqualityCheck(const Tup4& other)
{
return (a == other.a && b == other.b && c == other.c && d == other.d);
}
};
然后您的 Point4 和 Vec4 類可以具有呼叫父方法的多載相等運算子:
class Point4 : public Tup4
{
public:
bool operator==(const Point4& other)
{
return EqualityCheck(other);
}
};
uj5u.com熱心網友回復:
Tup4 是一個概念而不是一個類。Vec4 和 Point4 滿足這個概念。
大多數 Vec4 和 Point4 都是作為模板實作的。
在極少數情況下,您需要以運行時多型方式處理 Tup4s,不要使用繼承,像 std 函式一樣使用型別擦除。但你可能不會。
struct Tup4Data{
double v[4];
};
template<class D>
struct Tup4Impl:Tup4Data{
// common implementation details of Tup4
// D is derived class (Vec4 or Point4)
};
struct Vec4:Tup4Impl<Vec4>{
// extra stuff for Vec4
};
struct Point4:Tup4Impl<Point4>{
// extra stuff for Poimt4
};
現在,只想處理原始雙打而不關心的代碼可以采用Tup4Data. Tup4Impl如果要查找,請使用 CRTP;這提供了靜態多型性。
那些關心它是向量還是點的人可以選擇任何一個。
那些想要兩者兼而有之的人可以是模板代碼或型別擦除。
最后一種情況——型別擦除——更難,但作為交換,你在其他情況下都會得到巨大的改進。99% 的代碼庫甚至不需要鍵入擦除。
我什至不確定什么樣的情況有代碼想要在這里輸入擦除。
所以不用擔心。(如果您想學習,請查找示例 std 函式實作)。
uj5u.com熱心網友回復:
您可以為此使用模板。
實際上,將類似值的型別(例如數學向量和指向物件層次結構)硬塞入 OOP 并不是一個好的用途。物件層次結構意味著使用“參考語意”;而向量、元組和點想要成為值。
例如,看看 C 標準庫如何實作復數。它將它們實作為一個類模板,引數化了您想要使用的數字型別,例如 float、double 等,然后多載算術運算子以處理complex<T>.
你將如何真正實作向量等類是相似的。
轉載請註明出處,本文鏈接:https://www.uj5u.com/yidong/391709.html
上一篇:如果值未定義,則為物件分配默認值
下一篇:無法從父類呼叫子類方法
