仍然有很多问题掌握指针,我试图不使用它们,但我不知道如何最好地完成以下操作。
我有两个类Point
和Ray
,我也确定可能已经有一个我应该使用的点类的实现。所以我有这两个类,我正在尝试创建一个光线,并最终将其传递给其他东西,但我收到一个错误:Thread
:EXC_BAD_ACCESS(code = 1,address = 0x0)`我按照我正在做的方式创建光线,然后尝试访问它。
class Point {
public:
float x;
float y;
Point();
Point(float x, float y);
~Point();
};
Point::Point() {
x = 0;
y = 0;
}
Point::Point(float xPos, float yPos) {
x = xPos;
y = yPos;
std::cout << "point created at: " << x << ", " << y << std::endl;
}
Point::~Point() {
std::cout << "point destroyed" << std::endl;
}
class Ray {
public:
std::unique_ptr<Point> origin;
float angleInRadians;
float length;
float slope();
Point* pointAtDistance(float percentage);
Point* pointAtYPos(float yPos);
Ray(Point& origin, float angleInRadians, float length);
~Ray();
};
Ray::Ray(Point& origin, float angleInRadians, float length) {
origin = std::move(origin);
angleInRadians = angleInRadians;
length = length;
}
float Ray::slope() {
return tanf(angleInRadians);
}
Point* Ray::pointAtDistance(float percentage) {
return new Point(origin->x + (length * percentage) * cosf(angleInRadians), origin->y + (length * percentage) * sinf(angleInRadians));
}
Point* Ray::pointAtYPos(float yPos) {
float B = origin->y - (slope() * origin->x);
return new Point((yPos - B) / slope(), yPos);
}
Ray::~Ray() {
std::cout << "point released" << std::endl;
origin.release();
std::cout << "ray destroyed" << std::endl;
}
第三行是错误发生的地方。
std::unique_ptr<Point> point(new Point(x,y));
std::unique_ptr<Ray> ray(new Ray(*point, M_PI/4, 100));
std::cout << "RAY origin: " << ray->origin->x << ", " << ray->origin->y << std::endl;
答案 0 :(得分:4)
我相信这应该可行 - 我只是从代码中删除了所有指针并改为使用实例。在你的C ++知识水平上,指针几乎总是不必要的。
class Point {
public:
Point();
Point(float x, float y);
~Point();
float x;
float y;
};
Point::Point() {
x = 0;
y = 0;
}
Point::Point(float xPos, float yPos) : x(xPos), y(yPos) {
std::cout << "point created at: " << x << ", " << y << std::endl;
}
Point::~Point() {
std::cout << "point destroyed" << std::endl;
}
class Ray {
public:
Ray(const Point& origin, float angleInRadians, float length);
~Ray();
float slope();
Point pointAtDistance(float percentage);
Point pointAtYPos(float yPos);
Point origin;
float angleInRadians;
float length;
};
Ray::Ray(const Point& o, float a, float l) : origin(o), angleInRadians(a), length(l) {
}
float Ray::slope() {
return tanf(angleInRadians);
}
Point Ray::pointAtDistance(float percentage) {
return Point(origin.x + (length * percentage) * cosf(angleInRadians), origin.y + (length * percentage) * sinf(angleInRadians));
}
Point Ray::pointAtYPos(float yPos) {
float B = origin.y - (slope() * origin.x);
return Point((yPos - B) / slope(), yPos);
}
Ray::~Ray() {
std::cout << "ray destroyed" << std::endl;
}
希望这会让你开始。祝其他任务好运!
答案 1 :(得分:0)
您的代码有两个问题:导致您遇到崩溃的第一个问题是,Ray
构造函数中的分配是noops。在行
origin = std::move(origin);
origin
的出现都是指同一个变量(该变量是函数的局部变量)。因此,类中的变量保持un / default-initialized。对于智能指针,默认初始化意味着它包含一个NULL指针,当您访问它时会发生段错误。
但是,更改构造函数以使用初始化程序列表可以避免此问题
Ray::Ray(Point& origin, float angleInRadians, float length) :
origin(&origin), angleInRadians(angleInRadians), length(length)
{}
不会因代码中的第二个问题而移除崩溃:您为同一个对象构造了两个不同的unique_ptr<>
:第一个是名为unique_ptr<>
的{{1}},第二个是类point
中名为unique_ptr<>
的{{1}}。因此,您的程序会尝试销毁origin
对象两次,一次是变量Ray
超出范围,第二次是变量Point
超出范围。
当使用标准C ++库“智能”指针时,永远不要将智能指针转换为裸指针/引用,然后从该裸指针/引用重新创建智能指针。只要您只通过智能指针分配智能指针或通过引用传递智能指针,您就是安全的,但是您必须永远不要为同一个对象创建两个彼此不了解的智能指针。即使使用point
,也绝对不能这样做。如果你这样做,他们都会尝试做他们的工作,你会崩溃(希望如此)。