鱼C论坛

 找回密码
 立即注册
查看: 596|回复: 3

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

[复制链接]
发表于 2023-10-29 19:22:16 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
问题: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;  
    }  
};
最佳答案
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;
    }
};
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 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;
    }
};
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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
如果问题已经解决,请设置最佳答案
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 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 类的引用,同样也不会出现问题。

球一个最佳答案谢谢啦!这对我非常重要!
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-5 17:28

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表