[英]Operator overloading in C++ (operator-)
我正在開發一個程序來檢測一個三角形是否嵌套在另一個三角形中。
在這里,我創建了將x和y定義為雙精度的結構點。
struct Point {
double x;
double y;
};
這是我實現該結構的地方:
double eval (LineSegment line, Point p)
{
Point p1 = p - line.StartPoint;
Point p2 = line.EndPoint - line.StartPoint;
return p2.x * p2.y - p1.y * p2.x;
}
當我編譯時,它告訴我,“在'p-line.LineSegment :: StartPoint'中沒有匹配'operator-'。” 我真的不了解發生了什么,我想因為我一起使用它們不了解我想要哪個“點”?
我進行了研究,發現運算符重載,但這讓我感到困惑。 我真的不知道如何實現操作員重載。
如果有人可以告訴我如何精確地執行此操作,那將有所幫助。
這意味着編譯器不知道如何減去Point
對象。 它知道如何減去內置類型,但是要對自定義類型使用運算符,則需要提供行為。
在這種情況下,您可能想要以下內容:
struct Point
{
double x;
double y;
Point& operator-=( const Point& that )
{
x -= that.x;
y -= that.y;
return this;
}
};
Point operator-(Point first, const Point& second)
{
return first -= second;
}
有關更多指導,請參閱關於運算符重載的C ++-FAQ條目 。 那里有很多好的建議,可以幫助您避免一些陷阱,以及如何最大化代碼重用性和可讀性(這實際上意味着可維護性)的良好示例和建議。
在這種情況下,您還應該問自己是否要區分絕對坐標對和相對坐標對。 如果這樣做,則兩個點之間的差應該是Size
或Offset
,而不是Point
。 (如果您曾經在DateTime
和TimeSpan
類中使用過一個庫,那么您已經看到了這個概念的實際效果。C++本身將其用於標准庫的time_point
vs duration
,兩者都在命名空間std::chrono
time_point
找到。您有一個二維的版本。)
struct Point {
double x;
double y;
Point operator-(const Point& that) const
{
Point result;
result.x = this->x - that.x;
result.y = this->y - that.y;
return result;
}
};
如果要減去點,則需要提供一個重載運算符來實現。 C ++不會自動為類類型生成算術運算,因為大多數時候它們是沒有意義的。
這樣的事情應該做到:
Point operator-(Point lhs, Point rhs) {
return {lhs.x-rhs.x, lhs.y-rhs.y};
}
盡管我可能會為返回類型引入一種新類型( Vector
或Offset
或其他類型),以防止在應該使用點時使用點之間的偏移量的類別錯誤。
這是入門的基本草圖:
Point operator-( const Point& lhs, const Point& rhs )
{
Point result;
// make sure this is what you want:
result.x = lhs.x - rhs.x;
result.y = lhs.y - rhs.y;
return result;
}
請注意,這是一個自由函數,它不在Point
的定義之內。 隨便放。
看看http://www.cplusplus.com/doc/tutorial/classes2/ 。 它對操作符重載有很好的解釋。
您的代碼說的是從p中減去line.StartPoint。 但是,您的結構沒有該操作的已定義行為。 因此,除非您告訴編譯器如何對結構執行該操作,否則不能使用語法p - line.StartPoint
。
結構中的方法簽名可能看起來像這樣:
Point operator-(const Point &other) { }
您需要向該方法添加邏輯,以告訴編譯器如何在結構上執行減法運算。
如果將兩個數字加/減/乘...等,編譯器就會知道您的意思,一切都很好。 如果您想減去某個類,則編譯器並不固有地知道如何執行此操作(對於ANY類),但是為您提供了一個工具來定義如何將兩個類相減,並且看起來像這樣(使用Point類) :
Point operator-(Point p1, Point p2)
{
Point result;
result.x = p1.x - p2.x;
result.y = p1.y - p2.y;
return result;
}
現在,編譯器知道如何通過調用此函數減去兩點。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.