C++ 在静态方法中访问受保护的成员

C++ 在静态方法中访问受保护的成员,c++,touchgfx,C++,Touchgfx,我有一个不同宽度的圆圈。我创建了Screen1ViewBase类继承的子类,以访问WidthChange.cpp中的circlewidth。我可以进入圆圈宽度。但我无法在Screen1View.cpp中调用Change函数,因为它不是静态的。我将更改函数设置为静态,但这次我无法访问circlewidth和Screen1View的其他成员 #ifndef SCREEN1VIEWBASE_HPP #define SCREEN1VIEWBASE_HPP #include <gui/common

我有一个不同宽度的圆圈。我创建了Screen1ViewBase类继承的子类,以访问WidthChange.cpp中的circlewidth。我可以进入圆圈宽度。但我无法在Screen1View.cpp中调用Change函数,因为它不是静态的。我将更改函数设置为静态,但这次我无法访问circlewidth和Screen1View的其他成员

#ifndef SCREEN1VIEWBASE_HPP
#define SCREEN1VIEWBASE_HPP

#include <gui/common/FrontendApplication.hpp>
#include <mvp/View.hpp>
#include <gui/screen1_screen/Screen1Presenter.hpp>
#include <touchgfx/widgets/Box.hpp>
#include <touchgfx/widgets/canvas/Circle.hpp>
#include <touchgfx/widgets/canvas/PainterRGB565.hpp>

class Screen1ViewBase : public touchgfx::View<Screen1Presenter>
{
public:
    Screen1ViewBase();
    virtual ~Screen1ViewBase() {}
    virtual void setupScreen();

protected:
    FrontendApplication& application() {
        return *static_cast<FrontendApplication*>(touchgfx::Application::getInstance());
    }

    /*
     * Member Declarations
     */
    touchgfx::Box __background;
    touchgfx::Box box1;
    touchgfx::Circle circlewidth;
    touchgfx::PainterRGB565 circlewidthPainter;

private:

    /*
     * Canvas Buffer Size
     */
    static const uint16_t CANVAS_BUFFER_SIZE = 7200;
    uint8_t canvasBuffer[CANVAS_BUFFER_SIZE];
};

#endif // SCREEN1VIEWBASE_HPP
这是我的班级宣言

#ifndef WIDTHCHANGE_HPP    
#define WIDTHCHANGE_HPP 

#include <gui/screen1_screen/Screen1View.hpp>
#include <gui_generated/screen1_screen/Screen1ViewBase.hpp>

class WidthChange : public Screen1View
{

public:

    static void Change();

};

#endif
这是声明Change funct的地方

#include <gui/WidthChange.hpp>
#include <gui_generated/screen1_screen/Screen1ViewBase.hpp>
#include <gui/screen1_screen/Screen1View.hpp>
#include <gui/screen1_screen/Screen1Presenter.hpp>

void WidthChange::Change()
{
    float currentRad;
    float lineWidth;
    
    circlewidth.invalidate();

    circlewidth.getRadius(currentRad);
    if (currentRad >= lineWidthLimit)
    {
        circleWidthChangeFactor = -0.25;
    }
    else if (currentRad<= 15)
    {
        circleWidthChangeFactor = 0.25;
    }
    currentRad = currentRad + circleWidthChangeFactor;

    circlewidth.setRadius(currentRad);
    circlewidth.getLineWidth(lineWidth);
    circlewidth.setLineWidth(lineWidth + 2 * (circleWidthChangeFactor * (-1)));

    circlewidth.invalidate();
    }


<> P>我知道有很多事情,但是我不知道是否有一种方法来访问整个Stuts1VIEW成员和StutsVIEWBASE成员,当调用了更改函数时,

< P> C++中的静态成员函数只能访问静态成员数据或其他静态成员函数。Screen1View可以访问静态功能

如果回调需要进行一些复杂的ui设置/计算,那么使用这样的中间类可能是一个好主意。但是在这里创建Screen1View的子类是没有意义的,因为它的类型是View,而不是您想要的类型,而且会带来很多麻烦

如果您需要访问Screen1View中的成员,您可以定义一个具有非静态成员的类,并使用指向父级的指针来构造它,而不是使用继承,但实际上不建议为成员提供对其父级的那种访问

相反,我建议在类定义中使用更通用的函数。e、 人为的例子。这将允许您在视图回调处理程序中保留代码的清晰描述,而不是将其全部隐藏在helperclass中的某个函数中。这些函数可以是静态的

void HelperClass::setCircleRadiustouchgfx::圆*圆,浮动半径 { 圆.setradius半径; 使无效; } 如果我们假设CircleHelper现在更完整,那么视图中的处理程序代码将如下所示,并且可读性更高:

void Screen1View::someCallback { circlehalper::setRadius和myCircle,someValue; //更多呼叫在此执行您想要的操作。LineHelper::。。 //但是现在代码只传递它需要的信息。 //大多数情况下,无效是预期的,所以我们不希望 //读取100次失效;混乱 }
在TouchGFX设计器为您生成ui代码之前,我一直严重依赖静态助手类来完成繁琐的设置,这些设置通常会使设置屏幕变得杂乱无章,并且不会向任何人提供有价值的信息。

这里的继承结构对我来说没有多大意义。为什么WidthChange是从Screen1View继承的整个类?您确定它不应该只是Screen1View的一个成员函数来更改其宽度吗?特别是如果它应该发生在handleTickEvent中,那么你甚至不可能有Screen1View对象不支持更改宽度。如果它是Screen1View的成员函数,那么如果没有Screen1View中的对象引用,就不能调用它,对吗?是的。因为circlewidth和circleWidthChangeFactor以及lineWidthLimit都是成员变量,所以在没有特定Screen1View实例的情况下,如何进行更改?
#ifndef WIDTHCHANGE_HPP    
#define WIDTHCHANGE_HPP 

#include <gui/screen1_screen/Screen1View.hpp>
#include <gui_generated/screen1_screen/Screen1ViewBase.hpp>

class WidthChange : public Screen1View
{

public:

    static void Change();

};

#endif
#include <gui/WidthChange.hpp>
#include <gui_generated/screen1_screen/Screen1ViewBase.hpp>
#include <gui/screen1_screen/Screen1View.hpp>
#include <gui/screen1_screen/Screen1Presenter.hpp>

void WidthChange::Change()
{
    float currentRad;
    float lineWidth;
    
    circlewidth.invalidate();

    circlewidth.getRadius(currentRad);
    if (currentRad >= lineWidthLimit)
    {
        circleWidthChangeFactor = -0.25;
    }
    else if (currentRad<= 15)
    {
        circleWidthChangeFactor = 0.25;
    }
    currentRad = currentRad + circleWidthChangeFactor;

    circlewidth.setRadius(currentRad);
    circlewidth.getLineWidth(lineWidth);
    circlewidth.setLineWidth(lineWidth + 2 * (circleWidthChangeFactor * (-1)));

    circlewidth.invalidate();
    }