2016-12-26 3 views
0

n 몸체 문제를 모델링하는 데 사용하는 Point 구조체를 작성했습니다. 나는 완전히 이해하고 실현하기 어려웠다. 복사 & 스왑 이디엄을 주로 속도 인 나의 요구에 적응시켰다. 이 일을 제대로하고 있습니까? 그것은 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'로 제거해야합니다. 또한 모든 일반 산술 연산자 (+, not + =)를 값으로 반환하도록 변경하십시오. –

+2

'operator ='함수는 대입 연산자의 * 양쪽에있는 객체를 변경합니다. 또한 연산자의 오른쪽에있는 rvalues ​​("rvalue"의 "r"이 나타내는 것)와 함께 사용할 수 없습니다. 연산자는 스왑을 사용하는 경우 값 *으로, * 그렇지 않으면 * 상수 * 참조로 인수 *를 가져야합니다. –

답변

4

복사/스왑 ideom 실제로 사본 swap()의 값. 귀하의 "적응"은 단지 swap()s입니다. 복사/스왑 ideom의 올바른 사용은 다음과 같이, 예를 들어, 보일 것이다

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

(물론,이 또한 swap() 기능이 하나의 추가 인수를 복용 구성원인지 가정 이미이 입니다 교환 대상).

속도가 가장 중요한 문제인 경우 copy/swap-ideom은 Point의 경우에 적합하지 않을 수 있습니다. 복사 작업은 본질적으로 간단합니다. 값을 교환하는 것은 비교적 복잡한 작업 (예 : std::vector)을 복사하는 것과 비교하면 상당히 합리적입니다. 여기서 스왑 작업은 아마 여러 값 및 일부 할당 작업을 복사하는 것 외에 몇 가지 포인터 스왑으로 계산됩니다. 당신은 또한 하지new 새로운 Point 객체를 할당해야

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

으로 댓글에서 지적했다 : C의 ++는 자바 나 C#을하지 않습니다 그것은 당신의 Point 할당 그냥 모든 회원을 할당에 떨어져 아마 최고입니다 ! 힙에서 가져올 필요가없는 스택에 객체를 만들면됩니다 (예 :

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

자세한 답변과 다른 의견에 감사드립니다. 그에 따라 코드를 편집했습니다. – Sebastian