Accessing a protected member in a static method

548 Views Asked by At

I have a circle of varying width. I created a subclass that was inherited by Screen1ViewBase class, to access "circlewidth" in WidthChange.cpp. I could access the "circlewidth". But I couldn't call Change function in Screen1View.cpp, cause it wasn't static. I made Change function static but this time I couldn't access "circlewidth" and the other member of 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 SCREEN1VIEW_HPP
#define SCREEN1VIEW_HPP

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

class Screen1View : public Screen1ViewBase
{
public:
    Screen1View();
    virtual ~Screen1View() {}
    virtual void setupScreen();
    virtual void tearDownScreen();
    virtual void handleTickEvent();
protected:
    int lineWidthLimit;
    float circleWidthChangeFactor;
};

#endif // SCREEN1VIEW_HPP
#include <gui/screen1_screen/Screen1View.hpp>
#include <gui/WidthChange.hpp>


Screen1View::Screen1View()
{

}

void Screen1View::setupScreen()
{
    Screen1ViewBase::setupScreen();
}

void Screen1View::tearDownScreen()
{
    Screen1ViewBase::tearDownScreen();
}
void Screen1View::handleTickEvent()
{
    WidthChange::Change();
}

This is my class declaration

#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

This is where Change() funct is declared

#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();
    }

I know there are a lot of things about it but I wonder if there is a way to access whole Screen1View members and Screen1ViewBase members when the Change function is called.

1

There are 1 best solutions below

0
On

Static member functions in c++ can only access static member data, or other static member functions. Screen1View can access static functions.

Having an intermediary class like this can be a good idea if your callback needs to do some complex ui setup/calculations. But it doesn't make sense to create a subclass of Screen1View here because it's of type View which isn't what you want (also comes with a lot of baggage).

If you need access to the members in Screen1View you could define a class with non-static members and construct it with a pointer to the parent instead of using inheritance, but giving members that kind of access to their parent isn't really recommended.

What i suggest instead is to have more general functions in a class definition. e.g. (contrived example). This would allow you to keep a clear description of the code in your Views callback handlers instead of hiding it all away in some function in a helperclass. These functions could be static.

void HelperClass::setCircleRadius(touchgfx::Circle* circle, float radius)
{  
  circle.setRadius(radius);
  circle.invalidate();
}

If we pretend that CircleHelper was more complete now your handler code in the View would look like this and be much more readable:

void Screen1View::someCallback()
{
   CircleHelper::setRadius(&myCircle, someValue);
   //More calls here to do what you want. LineHelper::..
   //But now the code communicates only what it needs to.
   //Most often "invalidate" is expected, so we don't want to be
   //reading 100 occurrences of invalidate(); clutter
}

Before the TouchGFX Designer to generate ui code for you I've relied heavily on static helper classes to do tedious setup that usually just cluttered setupScreen() and provided no valuable information to anyone.