c++ - 如何使基类的方法使用派生类集的继承的受保护成员?C++
问题描述
我有一个问题,即使循环中的代码具有正确的指针类型(如对显示的调用) ,如果我没记错的话,tells()
它仍然使用getPointer()
默认构造的类。Triangle
如何调用getPointer()
循环返回指向保存坐标的内存的指针?
主.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;
}
三角形.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
三角形.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)
解决方案
这段代码中的主要问题是,当派生类的构造函数(除了此处未使用的之外的所有IsoscelesTriangle(QPointF ,uint, uint)
构造函数都被调用)时,它们会在自身内部调用其他构造函数,从而创建一个临时对象而不是初始化类字段。
此外,为封装起见points
,创建基类的私有成员并在基类中创建受保护的成员函数也是一个好主意。void setPoints(QPointF a, QPointF b, QPointF c)
固定构造函数看起来像这样:
三角形.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) { }
推荐阅读
- makefile - Make:在检查依赖项之前运行代码
- node.js - 在 React 上处理服务器端错误:Formik & Yup
- c++ - C ++程序在应该终止时重复
- java - 是否不需要在下面的代码中指定 public 或 public abstract ?
- python - 随机选择总是返回 1 作为答案(简单游戏)
- javascript - HTML 代码在 codepen 中工作,但在其他文本编辑器中不工作
- python - 在 Python 中导入未知模块
- r - 控制 R 中回归不连续性中的固定效应
- .htaccess - 在多个页面上重定向 url 查询字符串
- jpa - 分离实体是什么意思?