我有一个问题,尽管循环中的代码具有正确的指针类型(如调用到 tells()
显示)它仍然使用 getPointer()
在默认的构造上 Triangle
类,如果我没有说错的话,如何向 getPointer()
在循环中返回一个指向保存坐标的内存的指针?
main.cpp:
#include <triangles.h>
#include <memory>
#include<QVector>
class C {
public:
std::shared_ptr<Triangle> shp;
};
int main() {
QVector<C> vc;
C t, a, b;
t.shp = std::make_shared<Triangle>(10,20,30,40,50,60);
a.shp = std::make_shared<EqualTriangle>(10,20, 53);
b.shp = std::make_shared<IsoscelesTriangle>(10,20, 53, 152);
vc.push_back(t);
vc.push_back(a);
vc.push_back(b);
for(auto x: vc) {
const QPointF * p = x.shp->getPointer();
x.shp->tell();
qDebug() << (void*) p;
qDebug() << p[0]<< p[1]<<p[2];
}
return 0;
}
triangles. h:
#define TRIANGES_H
#include<QPointF>
#include<cmath>
#include<QDebug>
class Triangle
{
public:
Triangle() = default;
Triangle(float ax, float ay, float bx, float by, float cx, float cy);
Triangle(QPointF a, QPointF b, QPointF c);
const QPointF *getPointer() {qDebug() << "triangle getpoint called"; return points; }
virtual void tell() { qDebug()<<"triangle tells";}
protected:
QPointF points[3];
};
class IsoscelesTriangle : public Triangle
{
public:
IsoscelesTriangle() = default;
IsoscelesTriangle(QPointF point, uint side_len, uint base_len);
IsoscelesTriangle(float px, float py, uint side_len, uint base_len ): Triangle() {
IsoscelesTriangle(QPointF(px, py), side_len, base_len);
virtual void tell() { qDebug()<<"iso triangle tells";}
};
class EqualTriangle : public IsoscelesTriangle
{
public:
EqualTriangle() = default;
EqualTriangle(QPointF point, uint side_len ):IsoscelesTriangle() { IsoscelesTriangle(point, side_len, side_len);}
EqualTriangle(float px, float py, uint side_len) :IsoscelesTriangle() {
EqualTriangle(QPointF(px,py), side_len);
}
virtual void tell() { qDebug()<<"equal triangle tells";}
};
#endif // TRIANGES_H
triangles. cpp:
#include "triangles.h"
#include <QDebug>
Triangle::Triangle(float ax, float ay, float bx, float by, float cx, float cy)
{
points[0] = QPointF(ax, ay);
points[1] = QPointF(bx, by);
points[2] = QPointF(cx, cy);
}
Triangle::Triangle(QPointF a, QPointF b, QPointF c)
{
points[0] = a;
points[1] = b;
points[2] = c;
}
IsoscelesTriangle::IsoscelesTriangle(QPointF point, uint side_len, uint base_len) : Triangle()
{
points[0] = point;
points[1] = QPointF(point.x()+base_len, point.y());
points[2] = QPointF(point.x()+base_len/2, point.y() +sqrt(side_len*side_len - (base_len*base_len)/4));
}
三角形.cpp: 输出:
triangle getpoint called
triangle tells
0x560340e8fd38
QPointF(10,20) QPointF(30,40) QPointF(50,60)
triangle getpoint called
equal triangle tells
0x560340e8fd88
QPointF(0,0) QPointF(0,0) QPointF(0,0)
triangle getpoint called
iso triangle tells
0x560340e8fdd8
QPointF(0,0) QPointF(0,0) QPointF(0,0)
这段代码的主要问题是,当派生类的构造函数(除了这里没有使用的 IsoscelesTriangle(QPointF ,uint, uint)
调用,它们会在自己内部调用额外的构造函数,从而创建一个临时对象,而不是初始化类字段。
另外,最好是将 points
一个基类的私有成员,并创建一个受保护的成员函数。void setPoints(QPointF a, QPointF b, QPointF c)
的基类中,为了封装的缘故。
固定构造函数会是这样的。
triangles.cpp
IsoscelesTriangle::IsoscelesTriangle(QPointF point, uint side_len, uint base_len)
{
QPointF a = point;
QPointF b = QPointF(point.x()+base_len, point.y());
QPointF c = QPointF(point.x()+base_len/2, point.y() +sqrt(side_len*side_len - (base_len*base_len)/4));
setPoints(a,b,c);
}
三角形.h
IsoscelesTriangle(float a, float b, uint side_len, uint base_len):IsoscelesTriangle(QPointF(a,b), side_len, base_len) {}
EqualTriangle(QPointF point, uint side_len ): IsoscelesTriangle(point, side_len, side_len) { }
EqualTriangle(float x, float y, uint side_len ): IsoscelesTriangle(QPointF(x,y), side_len, side_len) { }