如何使基 class 的方法使用派生 class 集的继承的受保护成员? C++
How to make method of a base class use inherited protected members that derived class sets? C++
我有一个问题,即使循环中的代码具有正确的指针类型(如对 tells()
的调用所示)它仍然使用 getPointer()
而不是默认构造的 Triangle
class,如果我没记错的话。
如何在循环 return 中调用 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));
}
输出:
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)
此代码中的主要问题是,当派生的 classes 的构造函数(除了此处未使用的 IsoscelesTriangle(QPointF ,uint, uint)
之外的所有构造函数被调用时,它们会调用自身内部的其他构造函数,从而创建一个临时对象而不是初始化class 个字段。
此外,将 points
设为基 class 的私有成员并在基 class 中创建受保护的成员函数 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);
}
triangles.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) { }
我有一个问题,即使循环中的代码具有正确的指针类型(如对 tells()
的调用所示)它仍然使用 getPointer()
而不是默认构造的 Triangle
class,如果我没记错的话。
如何在循环 return 中调用 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));
}
输出:
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)
此代码中的主要问题是,当派生的 classes 的构造函数(除了此处未使用的 IsoscelesTriangle(QPointF ,uint, uint)
之外的所有构造函数被调用时,它们会调用自身内部的其他构造函数,从而创建一个临时对象而不是初始化class 个字段。
此外,将 points
设为基 class 的私有成员并在基 class 中创建受保护的成员函数 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);
}
triangles.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) { }