0

Basically I have a class that has multiple QString values, a constructor, and a method. The object gets it's 'values' set in the constructor. Then I need to call the method, toString() using the object to return the assigned value. How can I do this as when I try I get invalid use of non-static data member 'DisconnectReason::BANNED'. Any help is greatly appreciated!

Class:

class DisconnectReason
{
public:
    QString BANNED = "B&";
    QString IDLE_TIMEOUT = "it";
    QString KICKED = "k";
    QString MANUAL = "man";
    QString PING_TIMEOUT = "pt";
    QString reason;
    DisconnectReason(const QString reason)
    {
        this->reason = reason;
    }
public:
    virtual QString toString()
    {
        return reason;
    }
};

Interface.cpp

#include "interface.h"
#include "ui_interface.h"
#include <QDebug>
#include "constants.h"

Interface::Interface(QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::Interface)
{
    ui->setupUi(this);
    DisconnectReason *dr = new DisconnectReason(DisconnectReason::BANNED);//Error here
    qDebug() << dr->toString();
}

Interface::~Interface()
{
    delete ui;
}
Nicholas Johnson
  • 1,012
  • 2
  • 12
  • 35
  • 1
    Seems like the error is perfectly clear -- that QString isn't declared as static, but you're trying to use it as though it were. Either you need to instantiate an instance of the DisconnectReason class and get the string from there, or make that QString static. – MrEricSir Feb 14 '17 at 04:25

1 Answers1

2

Since BANNED variable (and others) is declared as a non-static member, you can't use it like DisconnectReason::BANNED. Only static members can be used like that.

There's two options:

  • Declaring those variables as static members

  • Using integral enum and assign them their strings in toString method.


Declaring static

class DisconnectReason
{
public:
    static const QString BANNED;
    /* others */

    DisconnectReason(const QString &reason)
    {
        this->reason = reason;
    }

    virtual QString toString()
    {
        return reason;
    }
};

// .cpp
const QString DisconnectReason::BANNED = "B&";
/* others */

As it's shown above, you can't initialize those variables in-class. You should instead initialize them out-side of your class (in a .cpp file), like what I've done. (Only constexpr expressions can be used as in-class initialization of static members)

This way, using DisconnectReason::BANNED is perfectly valid.

Using enum

class DisconnectReason
{
public:
    enum Reasons {
        BANNED,
        /* others */
    };

    DisconnectReason(const Reasons reason)
    {
        this->reason = reason;
    }

    virtual QString toString()
    {
        if(this->reason == BANNED){
            return "B&";
        }
        return "Unknown Reason";
    }
};
Community
  • 1
  • 1
frogatto
  • 28,539
  • 11
  • 83
  • 129
  • This looks very promising. Thank you, I will try when I get home! – Nicholas Johnson Feb 14 '17 at 12:31
  • This works very well. However, I have a `Constants.cpp` that has a Contructor for the Class: `Constants`. When I get a variable from this it says `undefined reference to 'DisconnectReason::BANNED'` – Nicholas Johnson Feb 15 '17 at 00:40
  • @NicholasJohnson `static` members should be _defined_ in a `.cpp` file. See [this](http://stackoverflow.com/questions/272900/undefined-reference-to-static-class-member) and [this](http://stackoverflow.com/questions/9110487/undefined-reference-to-a-static-member). – frogatto Feb 15 '17 at 05:51
  • So no variable declaration at all in the .h? – Nicholas Johnson Feb 15 '17 at 05:52
  • @NicholasJohnson edited my answer. `QString DisconnectReason::BANNED = "B&";` should be in a `.cpp`. – frogatto Feb 15 '17 at 05:53
  • I would *also* recommend `const` on top of `static`. A constant should be `const`, you don't want to accidentally assign to it. – Matthieu M. Feb 15 '17 at 12:29
  • @MatthieuM. You're absolutely right. All constants should be `const`. Edited my answer. – frogatto Feb 15 '17 at 12:44