2016-12-26 28 views
0

我已經寫了一個點結構我正在使用來模擬正文問題。我發現很難完全理解和實施交換成語,並使其適應我的需求,這主要是速度。我是否正確地做這件事?在C++ 17中會有所不同嗎?C++&交換/複製應用到一個點結構

#pragma once 
#include <algorithm> 

struct Point 
{ 
    double x, y, z; 

    explicit Point(double X = 0, double Y = 0, double Z = 0) : x(X), y(Y), z(Z) {} 
    void swap(Point&, Point&); 

    inline bool operator==(Point b) const { return (x == b.x && y == b.y && z == b.z); } 
    inline bool operator!=(Point b) const { return (x != b.x || y != b.y || z != b.z); } 

    Point& operator=(Point&); 
    Point& operator+(Point&) const; 
    Point& operator-(Point&) const; 
    inline double operator*(Point& b) const { return b.x*x + b.y*y + b.z*z; } // Dot product 
    Point& operator%(Point&) const; // % = Cross product 

    inline Point& operator+=(Point& b) { return *this = *this + b; } 
    inline Point& operator-=(Point& b) { return *this = *this - b; } 
    inline Point& operator%=(Point& b) { return *this = *this % b; } 

    Point& operator*(double) const; 
    Point& operator/(double) const; 

    inline Point& operator*=(double k) { return *this = *this * k; } 
    inline Point& operator/=(double k) { return *this = *this/k; } 
}; 

std::ostream &operator<<(std::ostream &os, const Point& a) { 
    os << "(" << a.x << ", " << a.y << ", " << a.z << ")"; 
    return os; 
} 

void Point::swap(Point& a, Point& b) { 
    std::swap(a.x, b.x); 
    std::swap(a.y, b.y); 
    std::swap(a.z, b.z); 
} 

Point& Point::operator=(Point& b) { 
    swap(*this, b); 
    return *this; 
} 

Point& Point::operator+(Point& b) const { 
    Point *p = new Point(x + b.x, y + b.y, z + b.z); 
    return *p; 
} 

Point& Point::operator-(Point& b) const { 
    Point *p = new Point(x - b.x, y - b.y, z - b.z); 
    return *p; 
} 

Point& Point::operator%(Point& b) const { 
    Point *p = new Point(
     y*b.z - z*b.y, 
     z*b.x - x*b.z, 
     x*b.y - y*b.x 
); 

    return *p; 
} 

Point& Point::operator*(double k) const { 
    Point *p = new Point(k*x, k*y, k*z); 
    return *p; 
} 

Point& Point::operator/(double k) const { 
    Point *p = new Point(x/k, y/k, z/k); 
    return *p; 
} 
+5

看起來像你的代碼像篩子一樣泄漏內存。 –

+0

您需要從代碼中刪除所有指針和所有對'new'的調用。還要更改所有正常的算術運算符(+,不是+ =)以按值返回。 –

+2

您'operator ='函數更改賦值運算符的* both *兩邊的對象。它也不能用於運算符右側的右值(類似於「右值」中的「r」)。如果你使用交換,操作員應該通過值*來取其參數*,如果不是,則通過*常數*參考取其參數*。 –

回答

4

複製/交換,ideom實際拷貝swap() S中的值。你的「改編」僅僅是swap()s。正確的使用複製/交換-ideom會看,比如,像這樣:

Point& Point::operator= (Point other) { // note: by value, i.e., already copied 
    this->swap(other); 
    return *this; 
} 

(當然,這也假定您的swap()功能是考慮只是一個額外的參數成員:有已經與之交換的對象)。

如果速度是您最關心的問題,那麼複製/交換代碼可能不適用於Point的情況:複製操作本質上是微不足道的。與相對涉及的操作相比,交換值是相當合理的,例如將舊數組複製一個std::vector,其中除了複製可能的多個值和一些分配操作之外,交換操作僅僅指向幾個指針交換。也就是說,你的Point分配可能是最好的關閉只是分配所有成員:

Point& Point::operator= (Point const& other) { // note: no copy... 
    this->x = other.x; 
    this->y = other.y; 
    this->z = other.z; 
    return *this; 
} 

正如指出的評論,你也應該分配新Point對象與new:C++是不是Java或C# !你可以在堆棧上創建一個物體,它不需要來自堆,例如:

Point Point::operator+ (Point const& other) const { 
    return Point(this->x + other.x, this->y + other.y, this->z + other.z); 
} 
+0

感謝您的詳細解答並感謝其他意見。我相應地編輯了我的代碼。 – Sebastian

相關問題