2207122216 发表于 2023-10-29 19:22:16

point类 里要用line类 但是line类 也要用point类 ,有先后问题会报错怎么解决

问题:point类 里要用line类但是line类 也要用point类 ,有先后问题会报错怎么解决



定义一个 point 类,表示二维平面的一个点。
从中派生一个 line 类,由两个点确定一条直线。以成员函数形式实现以下功能:
1. 点到直线距离
2. 直线间距离(相交距离为 0)
3. 点在平面上的投影点
4. 直线与直线的交点。哈达马积



#include <iostream>
#include <cmath>

class Point {
public:
    double x, y;

    Point(double x = 0, double y = 0) : x(x), y(y) {}

    double distanceToLine(const Line& line) const {
      // 计算点到直线的距离
      double px = x;
      double py = y;
      double ax = line.p1.x;
      double ay = line.p1.y;
      double bx = line.p2.x;
      double by = line.p2.y;
      double numerator = fabs((by - ay) * px - (bx - ax) * py + bx * ay - by * ax);
      double denominator = sqrt((bx - ax) * (bx - ax) + (by - ay) * (by - ay));
      return numerator / denominator;
    }
};

class Line {
public:
    Point p1, p2;

    Line(const Point& p1, const Point& p2) : p1(p1), p2(p2) {}

    double distanceToLine(const Line& otherLine) const {
      // 计算两条直线之间的距离(相交距离为0)
      double ax = p1.x;
      double ay = p1.y;
      double bx = p2.x;
      double by = p2.y;
      double px = otherLine.p1.x;
      double py = otherLine.p1.y;
      double qx = otherLine.p2.x;
      double qy = otherLine.p2.y;
      double denominator = (qy - py) * (bx - ax) - (qx - px) * (by - ay);
      if (denominator == 0) {
            // 两条直线平行或重合,相交距离为0
            return 0;
      } else {
            // 两条直线相交,计算交点坐标并返回距离
            double t = ((qx - px) * (ay - py) - (qy - py) * (ax - px)) / denominator;
            Point intersectionPoint(ax + t * (bx - ax), ay + t * (by - ay));
            return intersectionPoint.distanceToLine(otherLine);
      }
    }

    Point projection(const Point& point) const {
      // 计算点在平面上的投影点
      double ax = p1.x;
      double ay = p1.y;
      double bx = p2.x;
      double by = p2.y;
      double px = point.x;
      double py = point.y;
      double t = ((px - ax) * (bx - ax) + (py - ay) * (by - ay)) / ((bx - ax) * (bx - ax) + (by - ay) * (by - ay));
      Point projectionPoint(ax + t * (bx - ax), ay + t * (by - ay));
      return projectionPoint;
    }
};

isdkz 发表于 2023-10-29 19:22:27

问题的原因是在point类中使用了line类,而在line类中又使用了point类,导致了循环依赖问题。解决这个问题的方法是使用前向声明(forward declaration)来解决类之间的依赖关系。

在point类的定义之前,添加line类的前向声明:

class Line;

这样就可以在point类中使用line类了。而在line类中使用point类时,由于point类的定义已经在line类的定义之后,所以不会出现依赖问题。

修改后的代码如下:

#include <iostream>
#include <cmath>

class Line; // 前向声明

class Point {
public:
    double x, y;

    Point(double x = 0, double y = 0) : x(x), y(y) {}

    double distanceToLine(const Line& line) const {
      // 计算点到直线的距离
      double px = x;
      double py = y;
      double ax = line.p1.x;
      double ay = line.p1.y;
      double bx = line.p2.x;
      double by = line.p2.y;
      double numerator = fabs((by - ay) * px - (bx - ax) * py + bx * ay - by * ax);
      double denominator = sqrt((bx - ax) * (bx - ax) + (by - ay) * (by - ay));
      return numerator / denominator;
    }
};

class Line {
public:
    Point p1, p2;

    Line(const Point& p1, const Point& p2) : p1(p1), p2(p2) {}

    double distanceToLine(const Line& otherLine) const {
      // 计算两条直线之间的距离(相交距离为0)
      double ax = p1.x;
      double ay = p1.y;
      double bx = p2.x;
      double by = p2.y;
      double px = otherLine.p1.x;
      double py = otherLine.p1.y;
      double qx = otherLine.p2.x;
      double qy = otherLine.p2.y;
      double denominator = (qy - py) * (bx - ax) - (qx - px) * (by - ay);
      if (denominator == 0) {
            // 两条直线平行或重合,相交距离为0
            return 0;
      } else {
            // 两条直线相交,计算交点坐标并返回距离
            double t = ((qx - px) * (ay - py) - (qy - py) * (ax - px)) / denominator;
            Point intersectionPoint(ax + t * (bx - ax), ay + t * (by - ay));
            return intersectionPoint.distanceToLine(otherLine);
      }
    }

    Point projection(const Point& point) const {
      // 计算点在平面上的投影点
      double ax = p1.x;
      double ay = p1.y;
      double bx = p2.x;
      double by = p2.y;
      double px = point.x;
      double py = point.y;
      double t = ((px - ax) * (bx - ax) + (py - ay) * (by - ay)) / ((bx - ax) * (bx - ax) + (by - ay) * (by - ay));
      Point projectionPoint(ax + t * (bx - ax), ay + t * (by - ay));
      return projectionPoint;
    }
};

陶远航 发表于 2023-10-29 19:22:58

你的代码中存在一个问题,那就是在定义Point类的时候,你试图使用Line类,但是在这个时候Line类还没有被定义。这就导致了编译器报错。这是一个常见的问题,通常被称为“循环依赖”或“循环引用”。

解决这个问题的一种方法是使用前向声明。前向声明就是在实际定义一个类之前先声明它。这样,编译器就知道这个类的存在,而不需要知道它的所有细节。在你的代码中,你可以在Point类定义之前添加一个Line类的前向声明。

这是修改后的代码:

#include <iostream>
#include <cmath>

class Line;// 前向声明

class Point {
public:
    double x, y;

    Point(double x = 0, double y = 0) : x(x), y(y) {}

    double distanceToLine(const Line& line) const;
};

class Line {
public:
    Point p1, p2;

    Line(const Point& p1, const Point& p2) : p1(p1), p2(p2) {}

    // ... 其他成员函数 ...
};

// 现在我们可以在Point类外部定义distanceToLine函数
double Point::distanceToLine(const Line& line) const {
    // ... 计算点到直线的距离 ...
}


注意,由于前向声明只告诉编译器Line是一个类,而不提供任何关于这个类的详细信息,所以在Point类中我们不能定义任何需要知道Line类内部结构的函数。因此,我们需要在Point类外部定义distanceToLine函数,这时Line类已经被完全定义了。
请注意,本回答来自GPT-4
如果问题已经解决,请设置最佳答案

Mike_python小 发表于 2023-10-29 19:23:38

这个问题可以通过前向声明解决。在 point 类和 line 类的定义中,互相引用了对方的类名,导致编译器无法确定类的大小,从而报错。

为了解决这个问题,可以在 point 类的定义之前加上 line 类的前向声明,这样编译器就能够知道 line 类的存在,并分配足够的空间。具体实现如下:


class Line; // 前向声明

class Point {
public:
    double x, y;

    Point(double x = 0, double y = 0) : x(x), y(y) {}

    double distanceToLine(const Line& line) const;
    Point projection(const Line& line) const;
};

class Line {
public:
    Point p1, p2;

    Line(const Point& p1, const Point& p2) : p1(p1), p2(p2) {}

    double distanceToLine(const Line& otherLine) const;
    Point intersection(const Line& otherLine) const;
};


在 point 类中,我们使用了 line 类的引用,但是由于我们提前声明了 line 类,所以编译器不会出现先后顺序的问题。

在 line 类中也可以使用 point 类的引用,同样也不会出现问题。

球一个最佳答案谢谢啦!这对我非常重要!{:10_254:}{:10_254:}{:10_254:}
页: [1]
查看完整版本: point类 里要用line类 但是line类 也要用point类 ,有先后问题会报错怎么解决