maemo.org - Talk

maemo.org - Talk (https://talk.maemo.org/index.php)
-   Development (https://talk.maemo.org/forumdisplay.php?f=13)
-   -   How to use enums (https://talk.maemo.org/showthread.php?t=71788)

XenGi 2011-04-04 09:57

How to use enums
 
Hi I made a class for notes and want to use an enum for a status like NEW or DELETED but I can't get it to work.
Heres the code:

note.h
Code:

#ifndef NOTE_H
#define NOTE_H

#include <QObject>

class Note : public QObject
{
    Q_OBJECT
public:
    Note(QString Text);
    Note(int Id, QString Text);
    enum Status;

private:
    int id;
    QString text;
    Status status;

};

#endif // NOTE_H

note.cpp
Code:

#include "note.h"

Note::Note(QString Text)
{
    id = NULL;
    text = Text;
    status = NEW;
}

Note::Note(int Id, QString Text)
{
    id = Id;
    text = Text;
    status = NORMAL;
}

enum Note::Status
{
    NORMAL = 0,
    NEW = 1,
    DELETED = 2
};

The resulting error message is "use of enum 'Status' without previous declaration". The error accours at the line " enum Status;" in note.h.

Can anyone tell me how to write this correctly?

nicolai 2011-04-04 10:09

Re: How to use enums
 
enums must be defined in the header file - not the cpp.

Joorin 2011-04-04 10:11

Re: How to use enums
 
The compiler is telling you what's wrong. The compiler is your friend.

"without previous declaration" indicates that you need to move the declaration of your enum to a place where it has been seen before you use it.

I'd suggest after the include and before the class declaration.

The compiler is your friend.

Joorin 2011-04-04 10:12

Re: How to use enums
 
Quote:

Originally Posted by nicolai (Post 981538)
enums must be defined in the header file - not the cpp.

No. Symbols need to be declared before they are used. If this enum was to be internal, it might very well be declared in the cpp file.

nicolai 2011-04-04 10:24

Re: How to use enums
 
Quote:

Originally Posted by Joorin (Post 981540)
No. Symbols need to be declared before they are used. If this enum was to be internal, it might very well be declared in the cpp file.

Yes you are right, but his:
Code:

public:
enum Status

looks like he doesn't want to use it internally only.

XenGi 2011-04-04 10:27

Re: How to use enums
 
Quote:

Originally Posted by Joorin (Post 981539)
I'd suggest after the include and before the class declaration.

So, I put that code between the include and class in the header file:

Code:

enum Status
{
    NORMAL = 0,
    NEW = 1,
    DELETED = 2
};

But I get the same error: "use of enum 'Status' without previous declaration".

And yes, I wanna use this enum also outside the class. ;)

Joorin 2011-04-04 10:29

Re: How to use enums
 
Quote:

Originally Posted by nicolai (Post 981547)
Yes you are right, but his:
Code:

public:
enum Status

looks like he doesn't want to use it internally only.

In this case it's part of the API but you wrote

Quote:

enums must be defined in the header file - not the cpp.
which is what commented on.

So, I think that we agree on how it should be done, you just got it a little bit too general in your answer.

nicolai 2011-04-04 10:41

Re: How to use enums
 
Code:

#ifndef NOTE_H
#define NOTE_H

#include <QObject>

class Note : public QObject
{
    Q_OBJECT
public:
    Note(QString Text);
    Note(int Id, QString Text);


enum Status
{
    NORMAL = 0,
    NEW = 1,
    DELETED = 2
};
private:
    int id;
    QString text;
    Status status;

};

#endif // NOTE_H


Joorin 2011-04-04 10:43

Re: How to use enums
 
Quote:

Originally Posted by XenGi (Post 981549)
So, I put that code between the include and class in the header file:

Code:

enum Status
{
    NORMAL = 0,
    NEW = 1,
    DELETED = 2
};

But I get the same error: "use of enum 'Status' without previous declaration".

And yes, I wanna use this enum also outside the class. ;)

So, I stripped away the Qt stuff and got this that compiles just fine:
Code:

enum Status
{
    NORMAL = 0,
    NEW = 1,
    DELETED = 2
};

class Note
{
public:
    Note();
    Note(int Id);

private:
    int id;
    Status status;

};

Note::Note()
{
    id = 0;
    status = NEW;
}

Note::Note(int Id)
{
    id = Id;
    status = NORMAL;
}

int main(int argc, char** argv) {
  Note foo;

  return 0;
}

Now look for differences apart from the Qt stuff.

Hint: Your enum is a symbol that's not part of the class. An enum is a place holder for integer values and nothing more. If you want to limit its visibility, use namespaces or declare it inside your class.

Hint 2: If you want to get help with compiling things, paste all of what the compiler is complaining about together with the offending part of code. In this case, a line number would have been nice.

Happy hacking.

XenGi 2011-04-04 11:55

Re: How to use enums
 
I'm now using the last version that nicolai has posted and everything works just fine. Thanks for your help. :)

The only problems I have now is my limited knowlage about * and & symbols before variables. so I have to deal with several "can not convert int* to int" errors.. :o

Maybe someone could post a little summary about the meaning of int i, int *i and int &i. And why my compiler forbids me to do the following:

QDateTime *time;
time = QDateTime::currentDateTime();

nicolai 2011-04-04 12:10

Re: How to use enums
 
Code:

Note::Note(QString Text)
{
    id = NULL;
    text = Text;
    status = NEW;
}

Just initialize your id variable with 0 instead of NULL.
NULL is used in C-code to initialize pointer variables with
a NULL-pointer. (In c++-code you can just use 0 for NULL-Pointer.)

Quote:

Originally Posted by XenGi (Post 981603)
Maybe someone could post a little summary about the meaning of int i, int *i and int &i.

http://www.infernodevelopment.com/si...and-references
http://www.parashift.com/c++-faq-lite/index.html
Quote:

Originally Posted by XenGi (Post 981603)
And why my compiler forbids me to do the following:

QDateTime *time;
time = QDateTime::currentDateTime();

Follow the advice from Joorin:
Quote:

Originally Posted by Joorin (Post 981561)
Hint 2: If you want to get help with compiling things, paste all of what the compiler is complaining about together with the offending part of code. In this case, a line number would have been nice.


Joorin 2011-04-04 13:37

Re: How to use enums
 
Quote:

Originally Posted by XenGi (Post 981603)
The only problems I have now is my limited knowlage about * and & symbols before variables. so I have to deal with several "can not convert int* to int" errors.. :o

Maybe someone could post a little summary about the meaning of int i, int *i and int &i.

int i;
TYPE INT
Can contain a signed integer (size depending on platform)

int *i;
POINTER TO TYPE INT
Can contain a (memory) pointer to TYPE INT. Pointers are typically implementation dependant but you can in most cases think of them as TYPE UNSIGNED INT. This means that you can do arithmetic with them (POINTER + POINTER, POINTER++ , ...).

int &i;
REFERENCE TO TYPE INT
Think of this as an alias for your variable. It is, in all interesting ways, the same thing as what it is referencing. References can never be unassigned. Entering a scope with an unassigned reference will generate a compilation error.

Examples:
Code:

int i;
i = 17;

int *pInteger = &i;

The i variable now is a container for the signed integer 17.

pInteger is a POINTER TO TYPE INT that points at the place in memory where this 17 is stored. The "&" operator returns POINTER TO TYPE <TYPE>. This is not the same as REFERENCE TO TYPE <TYPE>. Pointers can be unassigned or NULL or pointing at whatever you like, it's up to you to make sure it has a value that makes sense.

Code:

int &rInteger = i;
rInteger is now a REFERENCE TO TYPE INT and any time that you manipulate its value, you will at the same time change the value in the variable i.

This mostly boils down to CALLING BY VALUE or CALLING BY REFERENCE. By using references as arguments when you call a method, no copy of the arguments needs to be done. C++ offers this as a way to not having to use pointers all over the place but puts strict rules on the usage of references.

Code:

int j = *pInteger;
The "*" operator dereferences the pointer, as in, it follows the pointer and returns whatever it's pointing at.

j will now contain whatever pInteger is pointing at, which in this case will be 17.

Quote:

And why my compiler forbids me to do the following:

QDateTime *time;
time = QDateTime::currentDateTime();
Your time variable is of type POINTER TO TYPE QDateTime and I'm guessing that the method you're calling, currentDateTime(), returns an object and not a pointer to an object.

Look for the documentation for method and you'll know. The compiler most likely told you that it can't convert TYPE QDateTime to POINTER TO TYPE QDateTime. The compiler is your friend. Listen to it.

demolition 2011-04-04 15:41

Re: How to use enums
 
Pointers and references are great because the allow information to persist beyond its original scope. The best one can hope for, from value-data is to return a single object at the end a function.

Regarding pointers: always intialise them! If they're member variables, use an initialisation list on your constructor. Not least because you can test for an object, even if it's value is set to NULL (0). Howwever, you can't test an unset pointer. Uninitialised pointers are a massive invisible headache! Also, a pointer does not store data, it points to the place where it is stored. If the data does not exist, use 'new' to create a suitable container. Pointers are type-sensitive, unless you're using void * for function pointers, say.

Not having seen the code in motion, my guess is that you have
- created the pointer
- pointed it at a value, not the location of an object.
I also suspect that both QDateTime is non static i.e. an object definition rather than an object itself so another reason for the error. If it is static, you'll still get an error b/c of what the pointer's being asked to point at.

You need to
- create the pointer object (e.g. *pTime),
- point it at reference object, which may need creating/initialising.
- use the pointer. (to call a function say)

For example, to resolve this case you might create a (new) QDateTime obectj then call the currentTime() function whenever you need its output:

// create ptr and ref obj, which self inits
QDateTime *pTime = new QDateTime();

// get time
<Type> timeNow = pTime->currentTime();


- where <Type> is the correct type that the f'n returns.

Pointers and Refs just need practice. Try to learn what the compile errors mean in human, not compiler speak.

Good luck - look forward to seeing the software in devel!

ps Speaking from experience, match your new and delete operators carefully and be equally mindful about using const with pointers across scopes!

XenGi 2011-04-06 12:36

Re: How to use enums
 
Thanks for the explanation. Many things are clearer now.
When the program is ready I will upload it to extras-devel.
If you are interested in the current online version of it you can test it here: http://xengi.ath.cx/webnotes
The maemo version will be able to syncronice the notes between the phone and web version.

The source can be accessed here: http://xengi.ath.cx/svn/webnotes


All times are GMT. The time now is 16:23.

vBulletin® Version 3.8.8