Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Should I use Classes to conserve memory for Android deployment ?



  • Hello, I am using QT Creator 4.14.1, on Ubuntu Linux 20.04.1
    I am somewhat new to C++ and QT Creator. But I have written one program which runs perfectly, and I have started two new ones which are functional at their basic initial level.
    Looking forward at the final version of one of these I have come to a few conclusions. First, I would like to deploy it on Android. Second, it will be big, and third, I need to start planning for memory management or it will probably be too large for Android. Roughly estimated resources for the final version of this program include about 100 global doubles, perhaps 200 lineEdits, two labels and two buttons for each lineEdit, and a slot for each lineEdit and button, and 6 lines of code for each slot, mostly things like X = Y * Z, reading and writing to and from lineEdits. The program is based on a stacked widget which will eventually have roughly 30 pages. Each page is a different functionality that does not depend on features of the other pages, and I also realized I could easily write 30 separate programs and they would work on Android. I don’t want 30 different programs, I want to make a Swiss Army Knife program with many different uses.
    In my study of C++ I am looking at Classes. It seems I could put all the variables used for each page into a class, creating an instance of the class when the page is called, and destroy the instance when the page is closed. It seems like this would greatly conserve memory. I could also put my lines of code which would otherwise be in the slots into functions inside the classes to save even more memory. Then the slot would call a class function.
    My first question is if this sounds like a good strategy for conserving memory, or is there something better, perhaps in C++ or in QT Creator ? If this does sound like a good plan, my next question is if I can put entire slot functions into a class ? Each of the pages will have layouts. Is there any way to put the things on a page, or even a page itself, into a Class so it all only exists while the instance of the class exists ? Or does the stacked widget take care of this automatically by creating the objects when the page is opened, and destroying them when another page is opened ?



  • @Citabria said in Should I use Classes to conserve memory for Android deployment ?:

    my next question is if I can put entire slot functions into a class ?

    This question does not make any sense.
    A slot is nothing else than a function and usually functions belong to some class.

    @Citabria said in Should I use Classes to conserve memory for Android deployment ?:

    put the things on a page, or even a page itself, into a Class so it all only exists while the instance of the class exists ?

    How else should that class exist, if you dont create any instance?

    @Citabria said in Should I use Classes to conserve memory for Android deployment ?:

    Or does the stacked widget take care of this automatically by creating the objects when the page is opened, and destroying them when another page is opened ?

    No. You have to create the pages (page widgets) manually.
    Flipping the page won't destroy widgets on other pages.



  • I am trying to use my first Class declaration. Here is what my Class declaration looks like:

    class Velocity
    {
    public:
    double FeetSec = 100;
    double MetersSec;

    void RefDispVel()                   //Refresh the Velocity displays
    {
        ui->lineEdit_4->setText(FeetSec);
        ui->lineEdit_5->setText(MetersSec);
    }
    
    void ProcFPS()                      //calculate values from FPS when changed
    {
        MetersSec = (FeetSec * 0.3048);
    }
    

    };

    This declaration is in mainwindow.h The first problem I encountered is the two lines in the class function RefDispVel(). This produces an error that ui is an undeclared identifier. I tried a few things such as mainwindow.ui->lineEdit. Can you tell me how to make this work ? It works when it is inside a slot function instead, except that there the variable gets an undeclared identifier error which I hope is because I have not successfully created an instance of my class.

    The other problem is in mainwindow.cpp:

    void MainWindow::on_pushButton_8_clicked() //Velocity conversion menu button Slot
    {
    Velocity* Bob = new Velocity(); //dynamically create instance of Velocity class
    ui->stackedWidget->setCurrentIndex(3);
    }

    Here I have tried to dynamically create an instance named Bob of my Velocity Class when the stacked widget page is called, but apparently I don’t know the correct syntax. I get an error saying Bob is an unused variable. Please tell me how to do this correctly.



  • @Citabria
    Your first question has nothing to do with slots. ui is declared in the #include ui_mainwindow.h you have in your mainwindow.cpp. You can only use it while you are in your MainWindow class. (or similar if it is not MainWindow but some other MyWidget you are working on.) You cannot write a standalone class like Velocity and have it directly access ui. I'm afraid your desire to declare the class you show with its methods does not make much sense.

    In your second question, you create a new Velocity and assign it to Bob, but you do not use Bob, hence the warning. There is no connection at all between the two lines in that method.

    I suggest you read up some more on classes in C++.

    If your situation is that you are designing "pages" in Qt Designer, which you will show on a QStackedWidget, you can add your own methods in code to a class you define which derives from a QWidget class and uses the ui generated in the Designer code. A typical template looks like:

    mainwindow.h:

    #include <QMainWindow> 
     
    namespace Ui { 
    class MainWindow; 
    } 
     
    class MainWindow : public QMainWindow 
    { 
        Q_OBJECT 
     
    public: 
        explicit MainWindow(QWidget *parent = 0); 
        ~MainWindow(); 
    private: 
        Ui::MainWindow *ui; 
    }; 
    

    mainwindow.cpp

    #include "MainWindow.h" 
    #include "ui_MainWindow.h" 
     
    MainWindow::MainWindow(QWidget *parent) : 
        QMainWindow(parent), 
        ui(new Ui::MainWindow) 
    { 
        ui->setupUi(this); 
    }
    
    MainWindow::~MainWindow() 
    { 
        delete ui; 
    } 
    

    You can now add your own methods into your MainWindow class to add whatever functionality.

    This template applies even if it is not a main window but instead some other widget which will form a "page" on the stacked widget. And you can create an instance of that page widget and add it to the stacked widget via:

    MyWidget *myWidget = new MyWidget;
    theStackedWidget->addWidget(myWidget);
    

    Note that writing/using classes has nothing/little to do with "conserving memory". Classes are a logical way of writing your code with separated, re-usable functionality.



  • When I talk about using classes to conserve system memory, my understanding it that I can put variables and functions in a class and that until I create an instance of that class, the variables and functions don’t use system memory, and that after I destroy the instance of that class, the memory the class uses is freed again. If this is true I can make my program seem much smaller to the device because I would have only one class instantiated at a time, out of 30. My program, being like a bunch or smaller programs, needs only a small part of the program’s variables, functions, formulae, active at any time. I can see how a class puts a group of related things together which is nice. I was only going to use classes because I thought I could conserve resources this way.



  • @Citabria
    Functions/methods are static objects. The compiled code is in memory all the time, regardless of classes or not, or anything else. Making them class member methods makes no difference. Having said that, the space occupied by functions themselves is usually minimal --- it is the data allocated at runtime when they execute which is what occupies more space.

    The space occupied by class member variables is indeed only allocated when class instances are allocated. If that is done via new, and you delete instances when not needed, you will indeed limit the total memory used. But that is also true in general if you use new & delete, again regardless of classes.

    As said before, classes should allow you to organise your code better. And are strongly to be recommended. I would not use them just to "conserve resources this way".



  • Hi, Thank you for all your help. I am sorry I am slow. I’ve been programming in Delphi for the last 20+ years. I’ve been familiar with C, but these are my first works in C++, QT Creator, and Linux. The two C++ books in which I’ve been reading about Classes both use examples that are so completely different from my intended use here that it is difficult to relate to my application. But really, many of the things I have needed help on are because the syntax in QT Creator is sometimes quite different from what I see in C++ books.
    I’m still stuck in the same place right now. My program won’t compile because of the “unused variable” bob. ”Velocity* Bob = new Velocity();“
    I was thinking this was just a warning, that it would still compile, but it won’t compile with this line. I am also getting this warning: “potential leak of memory pointed to by ‘Bob’”. This second warning goes away when I add the destructor line. But it still won't compile. My program uses a stacked widget. One page of it is the menu. This is just a bunch of buttons. Pressing a button sends a signal to a slot. In that slot I have two things. There is a line to switch to the appropriate page of the stacked widget, and there is the call to create an instance of Velocity. On this page there is a (return to menu) button. It does two things. It has a line that sends us back to the menu page, and it has a line that is supposed to destroy bob. I must not have the destruct syntax right because it has this warning: use of undeclared identifier ‘Bob’. Here is that line: ”delete Bob;“
    If I take out the constructor and destructor lines, the program compiles and runs.
    I’m not really sure how to “use” bob to the satisfaction of the compiler. I’ve got a constructor and destructor. I’ve got a function in the class declaration that performs some math on some of the Class variables. The program will need to be able to make changes to these Class variables, from functions in mainwindow.cpp. I haven’t tried this yet because I haven’t got my first class working yet. I will want to display some of these variables in lineEdits. I am not sure if I can access these class variables from mainwindow.cpp, or what the syntax to do so, is, because I haven’t gotten my Class working yet.
    I will want to do several lines of math to these class variables. I have been intending to do this in class functions. I don’t know yet if I will be able to call a Class function from mainwindow.cpp, or what the syntax is. I can do this math from functions in mainwindow.cpp, instead of in class functions, but then I must be able to access the class variables. I’m sorry but I am thinking ahead to everything I know I need to continue my program using Classes. I guess it boils down to these questions:

    1. What do I do to make the call to create a Class instance compile ?
    2. What is the correct syntax for destroying the class instance ?
    3. What is the correct syntax for calling a class function from a function in mainwindow.cpp ?
    4. What is the correct syntax for using a class variable from a function in mainwindow.cpp ?

  • Lifetime Qt Champion

    @Citabria said in Should I use Classes to conserve memory for Android deployment ?:

    he syntax in QT Creator is sometimes quite different from what I see in C++ books

    There is no "QtCreator syntax". QtCreator is a C++ IDE, so syntax is C++ (with small extensions like signals/slots, but those are simple C++ macros).

    Unused variable means exactly what the error says: the variable is created, but not used. Please show the relevant code to get better answer.

    1. "What do I do to make the call to create a Class instance compile ?" - show the code first.
    2. "What is the correct syntax for destroying the class instance ?" - C++ basics, if allocated on the heap use "delete" keyword or deleteLater() method if it is QObject based object.
    3. "What is the correct syntax for calling a class function from a function in mainwindow.cpp ?" - C++ basics, objectInstance.classFunction() (if objectInstance is allocated on the stack) or objectInstance->classFunction (if objectInstance is allocated on the heap).
    4. "What is the correct syntax for using a class variable from a function in mainwindow.cpp ?" - please explain what you mean. What function? Public class variables are accessed from outside in the same way class functions are (expect you do not append () of course).


  • @Citabria said in Should I use Classes to conserve memory for Android deployment ?:

    The other problem is in mainwindow.cpp:
    void MainWindow::on_pushButton_8_clicked() //Velocity conversion menu button Slot
    {
    Velocity* Bob = new Velocity(); //dynamically create instance of Velocity class
    ui->stackedWidget->setCurrentIndex(3);
    }

    I commented on this code of yours which is causing trouble earlier.

    • Bob is a local variable to the method. You assign to it, but you never again read from it, and it goes out of scope at the end of the method. So this causes a compile-time "Unused variable" warning.

    • You assign a new Velocity to it, which allocates memory. But you never delete it. So this causes a memory leak at runtime.

    There is no relationship between Velocity and your QStackedWidget. And I don't know how you think they have anything to do with each other. I don't think your current Velocity has any logic to it or should be a candidate for being a class.

    Note that all of the above would apply just as much to Delphi as to C++


  • Moderators

    @Citabria said in Should I use Classes to conserve memory for Android deployment ?:

    My program won’t compile because of the “unused variable” bob. ”Velocity* Bob = new Velocity();“

    No.

    Unless, you order your compiler to tread warnings as errors (with the compiler option/argument -Werror)
    I would applaud you, if you use this, but its not default and people like to ignore warnings, so 99% of all c++ programmers won't have it on. 😔

    Can you post the actual compiler error message ? If you posted it before, I can't see it.
    Are you sure you included the header of "Velocity" class in mainwindow ?


Log in to reply