Reputation: 2902
I am using Qt in C++ and am struggling with an enum. Consider a case like the one below:
Clone on GitHub: https://github.com/jif/enum
// memberclass.h =======================================================
#ifndef MEMBERCLASS_H
#define MEMBERCLASS_H
#include <QObject>
class MemberClass : public QObject
{
Q_OBJECT
public:
enum ErrorType {
NoError,
IsError
};
explicit MemberClass(QObject *parent = 0);
void setError(ErrorType errorType);
MemberClass::ErrorType error() const;
void otherMethod();
private:
MemberClass::ErrorType mError;
};
#endif // MEMBERCLASS_H
// memberclass.cpp =======================================================
#include "memberclass.h"
#include <QDebug>
MemberClass::MemberClass(QObject *parent) :
QObject(parent)
{
mError = NoError;
qDebug() << "mError initialized.";
}
MemberClass::ErrorType MemberClass::error() const {
return mError;
}
void MemberClass::setError(ErrorType errorType) {
mError = errorType;
}
void MemberClass::otherMethod() {
qDebug() << " In otherMethod()...";
qDebug() << " mError = " << mError;
qDebug() << " NoError = " << NoError;
qDebug() << " IsError = " << IsError;
qDebug() << " End otherMethod()";
}
// parentclass.h =======================================================
#ifndef PARENTCLASS_H
#define PARENTCLASS_H
#include <QObject>
#include "memberclass.h"
class ParentClass : public QObject
{
Q_OBJECT
public:
explicit ParentClass(QObject *parent = 0);
void testEnumStuff();
private:
MemberClass objectMember;
MemberClass *pointerMember;
};
#endif // PARENTCLASS_H
// parentclass.cpp =======================================================
#include "parentclass.h"
#include <QDebug>
ParentClass::ParentClass(QObject *parent) :
QObject(parent)
{
pointerMember = new MemberClass(this);
}
void ParentClass::testEnumStuff() {
qDebug() << "Just initialized...";
qDebug() << " pointerMember::mError = " << pointerMember->error();
qDebug() << " objectMember::mError = " << objectMember.error();
qDebug() << "Calling otherMethod() on each member...";
qDebug() << " In pointerMember...";
pointerMember->otherMethod();
qDebug() << " In objectMember...";
objectMember.otherMethod();
qDebug() << " pointerMember::mError = " << pointerMember->error();
qDebug() << " objectMember::mError = " << objectMember.error();
qDebug() << "Done.";
}
// main.cpp =======================================================
#include <QCoreApplication>
#include "parentclass.h"
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
ParentClass parent;
parent.testEnumStuff();
return a.exec();
}
// enum.pro =======================================================
QT += core
QT -= gui
TARGET = enum
CONFIG += console
CONFIG -= app_bundle
TEMPLATE = app
SOURCES += main.cpp \
parentclass.cpp \
memberclass.cpp
HEADERS += \
parentclass.h \
memberclass.h
Working with the variable mError
of type ErrorType
doesn't work as expected (it takes on strange and inconsistent values during execution).
I get output like this:
mError initialized.
mError initialized.
Just initialized...
pointerMember::mError = 0
objectMember::mError = 0
Calling otherMethod() on each member...
In pointerMember...
In otherMethod()...
mError = 0
NoError = 0
IsError = 1
End otherMethod()
In objectMember...
In otherMethod()...
mError = 13498688
NoError = 0
IsError = 1
End otherMethod()
pointerMember::mError = 0
objectMember::mError = 13498688
Done.
Upvotes: 2
Views: 821
Reputation: 2146
You are not in fact getting an automatically generated constructor. The reason for this is that you will only be given such a constructor in a class which does not define a constructor at all. You define a constructor for MemberClass(QObject *parent = 0) but because it exists you are not assigned an automatically generated noargs constructor.
A similar but related example might illustrate the class of problem:
class Base
{
/*Has a constructor therefore does not get a free
noargs constructor*/
Base(int i) {};
};
class Derived : public Base
{
};
int main()
{
/*Not actually possible because Derived will get a free noargs constructor
which will attempt to invoke the non existant no args constructor of Base.
*/
Derived d;
return 0;
}
You can see the result here
Upvotes: 1
Reputation: 845
You never initialize the "objectMember" value in your ParentClass' constructor, but you do initialize the "pointerMember". I'd bet it's not coincidence that "objectMember" is also the value giving you issues in your test. I don't have QT, but what happens if you add
objectmember = *pointerMember;
to the constructor after you initialize the pointerMember? It's been a bit since I've played with C++, so I may be missing something obvious, but I'd bet this is your issue.
Also note that, last I played with it, Visual Studio's debugger tends to set all non-initialized values to 0 for the programmer. This does not happen once the code has actually been compiled (though I believe some compilers may do it, such as GCC), so it's possible that's why you're seeing this error and others are not. Because of this, it might help to make the value you're looking for be "IsError" - that way, the value you'll be looking for will be 1, and not the default uninitialized value.
Upvotes: 0
Reputation: 38062
I cloned your code run it and there was no problems.
I recommend you to clean your project and build it again.
Code looks also looks OK. I think compiler cache get corrupted during code modification (sometimes it happens) and wrong code was generated, clean project should fix it.
Upvotes: 1
Reputation: 3843
I just copied and pasted your code into a clean project. When compiled with Qt 4.8.0 using MSVC2010, everything appeared normal to me. Have you rebuilt your project and re-run qmake?
Upvotes: 1
Reputation: 1696
The MemberClass single argument constructor has line << "mError initialized."; that's absent in the output. Compiler generated default constructor is clueless of desired values for member variables, so if the memory allocated for these has garbage, this garbage is leaked..
Upvotes: 0
Reputation: 14471
In your declaration of a member here
private:
MemberClass objectMember;
You're not providing a parameter for the constructor. It's calling the default constructor for QObject (which is not in your code) and which does not initialize the enum.
Upvotes: 1
Reputation: 12832
You didn't define a default constructor for MemberClass
and a compiler supplied implicit one is used to initialize objectMember
in ParentClass
. The implicit constructor does not initialize mError
for you, thus the random value you get.
Either add a explicit default constructor to MemberClass
:
MemberClass::MemberClass() :
QObject(NULL), mError(NoError)
{
}
or a member initialization to ParentClass
:
ParentClass::ParentClass(QObject *parent) :
QObject(parent), objectMember(NULL)
{
pointerMember = new MemberClass(this);
}
Upvotes: 10
Reputation: 7919
if you define your object on the stack like :
MemberOfMyClass member;
when you go out of scope, your object information is lost
Upvotes: 0