应用于 Point 结构的 C++ 和交换/复制

标签 c++ copy-constructor

我已经编写了一个 Point 结构,用于对 n 体问题进行建模。我发现很难完全理解和实现 copy-and-swap 习惯用法并使其适应我的需求,主要是速度。我这样做正确吗?在 C++17 中会有所不同吗?

#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;
}

最佳答案

copy/swap-ideom 实际上复制了swap()的值。您的“适应”仅仅是 swap()s。 copy/swap-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;
}

正如评论中所指出的,您还应该使用new 分配新的Point 对象:C++ 不是Java 或C#!您可以只在堆栈上创建一个不需要来自堆的对象,例如:

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

关于应用于 Point 结构的 C++ 和交换/复制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41332341/

相关文章:

c++ - os_defines.h : fatal error: features. h 没有这样的文件或目录

c++ - 如何用一个信号量同步 3 个进程?

c++ - 复制列表初始化是否在概念上调用复制构造函数?

c++ - packaged_task 和 async 有什么区别

c++ - 具有相似索引的值的总和

c++ - 在 n 处计算六次独立运行的斐波那契数的最大和最小时间

java - 使用复制构造函数而不是 Object.clone 进行深度复制的正确方法

c++ - 构造函数和拷贝构造函数

c++ - 这是一个有效的 Copy Ctor 吗?

c++ - 禁止在没有用户定义构造函数的情况下显式复制数据成员