0

I've been trying to access another class variable, but I can't build the project. QtCreator doesn't show any error / alert. I'm trying to create a ToDo app as a University project and I need to access the name of the list to link the task to the list.

I'm sorry for this very simple question but I'm starting out both with C++ and Qt. I have already checked similar questions, but none of the answers work for me (100% my fault).

These are some code snippets:

ListManager.h
public:
    static QStringList listName;
ListManager.cpp
void ListManager::on_pushButton_addList_clicked(){
    QString nameList = QInputDialog::getText(this, tr("Add list"), tr("List name"), QLineEdit::Normal, tr("Untitled list"), &ok);
    listName += nameList; // saves the name of the list in a QStringList
}

In the class TaskManager.cpp I want to access the names to set the QComboBox labels.

TaskManager.cpp
#include "listmanager.h"
// more code
void ListManager::on_pushButton_addTask_clicked(){
    QStringList listsNames = ListManager::listName;
    addTaskDialog.comboBox->addItems(listsNames);
}

As I mentioned before I don't get any error / alert by both QtCreator & CppCheck. When I try to build the program I get these issues:

error: Undefined symbols for architecture arm64:
  "ListManager::listName", referenced from:
      ListManager::on_pushButton_addList_clicked() in listmanager.o
      TaskManager::on_pushButton_addTask_clicked() in taskmanager.o
error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [ToDoApp.app/Contents/MacOS/ToDoApp] Error 1

Any help would be much appreciated!

Hadron27
  • 17
  • 6
  • Trying to build on a ARM machine? Does your Qt version support ARM? If yes, have you configured the project correctly to build for ARM? – kiner_shah Jul 22 '22 at 11:20
  • Thank you very much @kiner_shah for your help. I'm trying to build on a MacBook Air M1 ARM. My Qt version supports ARM and I think I've correctly set my project to build for ARM as the app builds and runs correctly without these lines. – Hadron27 Jul 22 '22 at 11:44
  • Do you build the `ListManager.cpp` too in your project? `QStringList listName` declared, but is it defined? – vahancho Jul 22 '22 at 11:46
  • Thank you @vahancho for your comment! `ListManager.cpp` is part of the project (it's added in the .pro file). `QStringList listName` is declared in `ListManager.h` and defined in `ListManager.cpp` (maybe I've done something wrong in this part of the code, it seems correct to me, but I'm a newbie). – Hadron27 Jul 22 '22 at 11:52
  • 1
    How do you defined the `listName`? – vahancho Jul 22 '22 at 11:56
  • I declared it in `ListManager.h`: `static QStringList listName;`. I suppose that I defined it in `ListManager.cpp` with this line: `listName += nameList;`. Is it incorrect? How should I define it? Thank you again. – Hadron27 Jul 22 '22 at 12:01
  • 1
    The definition would be `QStringList ListManager::listName;`. Alternatively, you can define it inline in the header: `static inline QStringList listName;` (since C++17). – Scheff's Cat Jul 22 '22 at 12:47
  • 1
    `listName += nameList;` is just an _expression_ but not a _definition_. – Scheff's Cat Jul 22 '22 at 12:47
  • 1
    FYI: [error: non-const static data member must be initialized out of line](https://stackoverflow.com/a/61519399/7478597) – Scheff's Cat Jul 22 '22 at 12:50
  • Thank you very much to all of you!! It solved the problem. I'm very sorry for my silly answer, but as I'm starting out some things are still very confusing for me. – Hadron27 Jul 22 '22 at 13:24

1 Answers1

0

To your ListManager.cpp add a line (usually it is placed before any method implementaton) like the following

QStringList ListManager::listName;

This will instantiate the static variable. The declaration in the header file is just a declaration, then you have to create it somewhere in the code.

If you don't istantiate the variable the compiler will not give you any error but the linker does because it is not able to find the real istance of the variable.

I'd like to add a suggestion: avoid where possible the use of static variables. It's better that the external object TaskManager holds a reference to ListManager and use a data member,

Marco Beninca
  • 605
  • 4
  • 15
  • Thank you very much for your answer (it works!!) and your suggestion! I'll try to use a reference instead! – Hadron27 Jul 22 '22 at 13:27