如何让基类的方法使用派生类所设置的继承保护成员?C++

问题描述 投票:-1回答:1

我有一个问题,尽管循环中的代码具有正确的指针类型(如调用到 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) 
c++ oop inheritance protected
1个回答
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) { }
© www.soinside.com 2019 - 2024. All rights reserved.