Having trouble with my queue.

G

Gregory L. Hansen

I can't seem to make a queue of objects, using the STL queue. I'm trying
to make a little event manager, and I just want someplace to store events.
The method definitions for EventManager have been commented away to
nothing during debugging, but the headers look like

class Event
{
private:
Object* recipient;
int eventID;
public:
Event(Object* r, int e)
{recipient = r; eventID = e;}
~Event() {cout << "Event deleted.\n";}
Object* get_recipient() {return recipient;}
int get_id() {return eventID;}
};

class EventManager
{
private:
queue<Event> event_queue;
// void start();
// void pop();
public:
// void push(Event e);
// int num_in_queue() {return 0;}// event_queue.size();}
};

When I try to compile with CodeWarrior I get 40 error messages that don't
flag any of my code. I've copied them below, and it's error messages all
the way down.

Where did I go wrong?

Error : function call '__ct()' does not match
'Event::Event(Object *, int)'
'Event::Event(const Event &)'
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : undefined identifier 'erase'
(instantiating: 'deque<Event, allocator<Event>>')
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : identifier 'insert' redeclared
(instantiating: 'deque<Event, allocator<Event>>')
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : identifier 'insert' redeclared
(instantiating: 'deque<Event, allocator<Event>>')
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : identifier 'insert' redeclared
(instantiating: 'deque<Event, allocator<Event>>')
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : identifier 'insert' redeclared
(instantiating: 'deque<Event, allocator<Event>>')
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : undefined identifier 'pop_front'
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : call of non-function
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : expression syntax error
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : undefined identifier 'erase'
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : call of non-function
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : undefined identifier 'erase'
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : call of non-function
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : undefined identifier 'erase'
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : call of non-function
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : undefined identifier 'erase'
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : expression syntax error
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : call of non-function
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : call of non-function
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : undefined identifier 'pop_front'
(instantiating: 'deque<Event, allocator<Event>>')
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : function call '__ct()' does not match
'Event::Event(Object *, int)'
'Event::Event(const Event &)'
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : undefined identifier 'erase'
(instantiating: 'deque<Event, allocator<Event>>')
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : identifier 'insert' redeclared
(instantiating: 'deque<Event, allocator<Event>>')
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : identifier 'insert' redeclared
(instantiating: 'deque<Event, allocator<Event>>')
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : identifier 'insert' redeclared
(instantiating: 'deque<Event, allocator<Event>>')
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : identifier 'insert' redeclared
(instantiating: 'deque<Event, allocator<Event>>')
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : undefined identifier 'pop_front'
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : call of non-function
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : expression syntax error
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : undefined identifier 'erase'
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : call of non-function
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : undefined identifier 'erase'
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : call of non-function
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : undefined identifier 'erase'
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : call of non-function
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : undefined identifier 'erase'
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : expression syntax error
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : call of non-function
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : call of non-function
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>

Error : undefined identifier 'pop_front'
(instantiating: 'deque<Event, allocator<Event>>')
MSLHeaders++.h line 19 #include <MSLHeaders.PPC.mch>
 
A

Alf P. Steinbach

* Gregory L. Hansen:
class Event
{
private:
Object* recipient;
int eventID;
public:
Event(Object* r, int e)
{recipient = r; eventID = e;}
~Event() {cout << "Event deleted.\n";}
Object* get_recipient() {return recipient;}
int get_id() {return eventID;}
};

class EventManager
{
private:
queue<Event> event_queue;

Should be std::queue.

// void start();
// void pop();
public:
// void push(Event e);
// int num_in_queue() {return 0;}// event_queue.size();}
};

When I try to compile with CodeWarrior I get 40 error messages that don't
flag any of my code. I've copied them below, and it's error messages all
the way down.

Where did I go wrong?

Put the code above in a file, with a dummy definition of class Object,
and remember to #include <queue>.

Provide a dummy 'main'.

Compile and find any other errors.
 
A

Alf P. Steinbach

* Gregory L. Hansen:
class Event
{
private:
Object* recipient;

Consider using an interface (pure abstract class) here instead of
an Universal Base Class. UBCs are generally Evil.

Also, you may need some smart-pointer instead of a raw pointer.

Otherwise you risk referring to a non-existing Object.

int eventID;

Try to adopt some common convention for data member names.

If this isn't an adaptor to someone else's code, consider replacing
id's with derived classes; otherwise you'll end up with huge, redundant,
non-maintainable 'switch'-es everywhere.

Uh, consider that anyway! ;-)

public:
Event(Object* r, int e)
{recipient = r; eventID = e;}


~Event() {cout << "Event deleted.\n";}
Object* get_recipient() {return recipient;}

Should be 'const'.
int get_id() {return eventID;}

Ditto.

Generally 'recipient' instead of 'get_recipient' makes for more
readable client code.

};

class EventManager

'Manager' is an Evil name. A 'Manager' could be anything. If this
is a queue, consider naming e.g. 'EventQueue'.
 
G

Gregory L. Hansen

* Gregory L. Hansen:

Should be std::queue.

My compiler is pretty old and doesn't know what std means, and doesn't
seem to use namespaces.
Put the code above in a file, with a dummy definition of class Object,
and remember to #include <queue>.

Provide a dummy 'main'.

Compile and find any other errors.

Oh, it has a real definition of class Object and a non-dummy 'main'.
Everything else compiles and runs without error. I was sending events
straight from the generator to the destination-- it's a pretty simple and
non-networky program. Then I thought I'd try an event queue. I've played
with a queue of strings to make sure I know how they work, and the above
compiles perfectly fine when I give EventManager a queue of strings
rather than Events.
 
A

Alf P. Steinbach

* Gregory L. Hansen:
My compiler is pretty old and doesn't know what std means, and doesn't
seem to use namespaces.

There's no use discussing C++ if you aren't using C++. ;-)

Upgrade.

Oh, it has a real definition of class Object and a non-dummy 'main'.

That's what I assumed when I wrote the above advice.

It feels kind of dumb wasting time on helping you to help yourself and
then get back,

"oh by the way I don't need any advice and will just ignore it, I was just
asking for the fun of it".

I've played
with a queue of strings to make sure I know how they work, and the above
compiles perfectly fine when I give EventManager a queue of strings
rather than Events.

One difference, a requirement for use with standard collection classes, is
that std::string has a copy constructor.

It would be better if you had discovered that by yourself.
 
A

Alf P. Steinbach

* Alf P. Steinbach:
There's no use discussing C++ if you aren't using C++. ;-)

Upgrade.
....

One difference, a requirement for use with standard collection classes, is
that std::string has a copy constructor.

Sorry, these two statements should have been together.

In standard C++ you have an implicitly declared copy constructor, but it's
possible you don't have with your old non-namespace non-whatever
compiler; however, that wasn't why I wrote there is a difference, I wrote
that because it's late at night.

Doing what I earlier adviced you to do: the code compiles fine with
Visual C++ 7.1.
 
G

Gregory L. Hansen

* Gregory L. Hansen:

There's no use discussing C++ if you aren't using C++. ;-)

Upgrade.



That's what I assumed when I wrote the above advice.

It feels kind of dumb wasting time on helping you to help yourself and
then get back,

"oh by the way I don't need any advice and will just ignore it, I was just
asking for the fun of it".

Well, I wasn't sure what you'd thought I'd done.
One difference, a requirement for use with standard collection classes, is
that std::string has a copy constructor.

It would be better if you had discovered that by yourself.

I thought the compiler automatically supplied a copy constructor if one
isn't defined, doing a straight member by member copying. My
understanding was that a copy constructor isn't needed unless you need to
do something like copy an array that a pointer is pointing to rather than
just copying the pointer.
 
G

Gregory L. Hansen

* Alf P. Steinbach:

Sorry, these two statements should have been together.

In standard C++ you have an implicitly declared copy constructor, but it's
possible you don't have with your old non-namespace non-whatever
compiler; however, that wasn't why I wrote there is a difference, I wrote
that because it's late at night.

Doing what I earlier adviced you to do: the code compiles fine with
Visual C++ 7.1.

I gave it a try with my namespace-friendly CodeWarrior 3.0,

#include<iostream>
#include<queue>

using namespace std;

class Object
{
public:
void report() {cout << "Here I am.\n";}
};

class Event
{
private:
Object* recipient;
int eventID;
public:
Event(Object* r, int e)
{recipient = r; eventID = e;}

~Event() {cout << "Event deleted.\n";}
Object* get_recipient() {return recipient;}
int get_id() {return eventID;}
};

class EventManager
{
private:
queue<Event> event_queue;
// void start();
// void pop();
public:
// void push(Event e);
// int num_in_queue() {return 0;}// event_queue.size();}
};

int main()
{
EventManager em;

return 0;
}

And was told

Error : function call '__ct()' does not match
'Event::Event(Object *, int)'
'Event::Event(const Event &)'
deque line 503 explicit deque (size_type n, const T& value = T (),

Which I read as the copy constructor being there if needed--
Event::Event(Object *, int) is mine, Event::Event(const Event &) is
compiler-supplied.

The code it flagged is in the dequeue file,

explicit deque (size_type n, const T& value = T (),
const Allocator& alloc = Allocator ())
: data_allocator (alloc), start (this), finish (this),
length (0), map (0), map_size (0)

And I do not understand what it's trying to tell me there.
 
A

Alf P. Steinbach

* Gregory L. Hansen:
I gave it a try with my namespace-friendly CodeWarrior 3.0,

#include<iostream>
#include<queue>

using namespace std;

class Object
{
public:
void report() {cout << "Here I am.\n";}
};

class Event
{
private:
Object* recipient;
int eventID;
public:
Event(Object* r, int e)
{recipient = r; eventID = e;}

~Event() {cout << "Event deleted.\n";}
Object* get_recipient() {return recipient;}
int get_id() {return eventID;}
};

class EventManager
{
private:
queue<Event> event_queue;
// void start();
// void pop();
public:
// void push(Event e);
// int num_in_queue() {return 0;}// event_queue.size();}
};

int main()
{
EventManager em;

return 0;
}

That compiles fine with MSVC 7.1 and with g++ 3.4.2.

And was told

Error : function call '__ct()' does not match
'Event::Event(Object *, int)'
'Event::Event(const Event &)'
deque line 503 explicit deque (size_type n, const T& value = T (),

Which I read as the copy constructor being there if needed--
Event::Event(Object *, int) is mine, Event::Event(const Event &) is
compiler-supplied.
Yep.


The code it flagged is in the dequeue file,

explicit deque (size_type n, const T& value = T (),
const Allocator& alloc = Allocator ())
: data_allocator (alloc), start (this), finish (this),
length (0), map (0), map_size (0)

And I do not understand what it's trying to tell me there.

Probably that here's a call to the T (aka Event) default constructor.

The implementation should not be using the constructor shown above.

Having a default constructor is not a requirement on the element type
of a queue (or deque) element type.

In short, upgrade your compiler, don't add a dummy default constructor.

See

<url: http://home.no.net/dubjai/win32cpptut/html/w32cpptut_01_01_02.html>

for a short list of free compilers.
 
G

Gregory L. Hansen

* Gregory L. Hansen:

Probably that here's a call to the T (aka Event) default constructor.

The implementation should not be using the constructor shown above.

Having a default constructor is not a requirement on the element type
of a queue (or deque) element type.

In short, upgrade your compiler, don't add a dummy default constructor.
Darn.


See

<url: http://home.no.net/dubjai/win32cpptut/html/w32cpptut_01_01_02.html>

for a short list of free compilers.

I have a little upgradeability problem in that I have a ten year old
Macintosh that can't run OSX or Carbonized software. Or Windows or Linux
stuff. I just wanted to play with the STL a little, but I can roll my own
queue.

I did just try adding a dummy default constructor anyway, and it compiled,
so it looks like you were right about that.
 
A

Alf P. Steinbach

* Gregory L. Hansen:
I have a little upgradeability problem in that I have a ten year old
Macintosh that can't run OSX or Carbonized software. Or Windows or Linux
stuff. I just wanted to play with the STL a little, but I can roll my own
queue.

Well, this is warping away from C++, but anyway I googled for "c++ old mac"
and among the first few links found

<url: http://gamma.magnet.fsu.edu/install/mklinux/compiler/>

and

<url:
http://eshop.macsales.com/OSXCenter/XPostFacto/Framework.cfm?page=XPostFacto.html>

Perhaps that may help.

If not, try asking in a Macintosh-specific group.
 
G

Gregory L. Hansen

* Gregory L. Hansen:

Well, this is warping away from C++, but anyway I googled for "c++ old mac"
and among the first few links found

<url: http://gamma.magnet.fsu.edu/install/mklinux/compiler/>

and

<url:
http://eshop.macsales.com/OSXCenter/XPostFacto/Framework.cfm?page=XPostFacto.html>

Perhaps that may help.

If not, try asking in a Macintosh-specific group.

Those are out of my regime. But I'm just a casual hobbiest and I like
CodeWarrior's IDE, so I'll stay with that for now. I'm happy enough just
to know why it didn't work, instead of thinking that I must have done
something wrong. Thank you for that.
 
G

Gregory L. Hansen

* Gregory L. Hansen:

Consider using an interface (pure abstract class) here instead of
an Universal Base Class. UBCs are generally Evil.

I don't understand what you mean here.
Also, you may need some smart-pointer instead of a raw pointer.

Otherwise you risk referring to a non-existing Object.



Try to adopt some common convention for data member names.

If this isn't an adaptor to someone else's code, consider replacing
id's with derived classes; otherwise you'll end up with huge, redundant,
non-maintainable 'switch'-es everywhere.

By derived classes, do you mean something like:

class BaseEvent
{
private:
Object* recipient;
public:
BaseEvent (Object* r) : recipient(r);
Object* target() {return recipient;}
};

class ControlEvent : BaseEvent {};
class UpdateEvent : BaseEvent {};
class ResetEvent : BaseEvent {};

class ObjectThatReceivesEvents
{
private:
// stuff
public:
dispatch(ControlEvent* ) {control_member_function()};
dispatch(UpdateEvent* ) {update_member_function()};
dispatch(ResetEvent* ) {reset_member_function()};
};
 
A

Alf P. Steinbach

* Gregory L. Hansen:
I don't understand what you mean here.

A Universal Base Class is a class every other class is derived from.

One well-known such is MFC's CObject.

They just make everything hard (especially multiple inheritance).

A C++ pure abstract class is a class where every virtual member routine
is pure virtual, "= 0".

You can use that to provide everything class Event needs to know about
it recipients, without dragging in all the baggage of an UBC.

By derived classes, do you mean something like:

class BaseEvent
{
private:
Object* recipient;
public:
BaseEvent (Object* r) : recipient(r);
Object* target() {return recipient;}
};

class ControlEvent : BaseEvent {};
class UpdateEvent : BaseEvent {};
class ResetEvent : BaseEvent {};

class ObjectThatReceivesEvents
{
private:
// stuff
public:
dispatch(ControlEvent* ) {control_member_function()};
dispatch(UpdateEvent* ) {update_member_function()};
dispatch(ResetEvent* ) {reset_member_function()};
};

Basically yes, except that I wouldn't use raw pointers -- references are
much better -- and I'd let ObjectThatReceivesEvents implement a receiver
interface for each event class it handles in a custom way, those things
defaulting via the receiver interface class hierarchy, and, well,
there's a _lot_ to say about event dispatching but I think that's enough to
get you going (when efficiency isn't an issue it's a lot easier in languages
that support introspection, such as Java and C#, but enough).
 
G

Gregory L. Hansen

* Gregory L. Hansen:

A Universal Base Class is a class every other class is derived from.

One well-known such is MFC's CObject.

They just make everything hard (especially multiple inheritance).

A C++ pure abstract class is a class where every virtual member routine
is pure virtual, "= 0".

You can use that to provide everything class Event needs to know about
it recipients, without dragging in all the baggage of an UBC.

I have a UBC for my objects, mainly because of the rigorous type checking
of C++. If I have an object that could be told to get data from another
object of ClassA or of ClassB, the pointer needs to be compatible with
both of them. An event can be given any destination pointer. I wasn't
sure whether events are normally shared or if each class has its
own unique set of events for each action, but I saw no harm in sharing.

My base class isn't really pure virtual-- all the member functions have a
cout to report, basically, that a member function of a derived class
hadn't been defined yet. It was useful before I had derived classes to
play with, and I saw no harm in leaving it that way as a debugging aid.
It's also been accumulating member functions as derived classes gained
different functions to be called for data. That didn't seem quite OOPy to
me, but it saves me from having to deal with upcasting. E.g., if a
derived class had a temperature() function but the base class didn't,
temperature() couldn't normally be called from a base class pointer.

Maybe I just don't know what I'm doing, but C++ seems to make it harder
than it has to be to do stuff that must be pretty common in OOP.
Basically yes, except that I wouldn't use raw pointers -- references are
much better --

I've always sort of thought of references as a different notation for
pointers. But I understand pointers, references have always made me a
little nervous.
and I'd let ObjectThatReceivesEvents implement a receiver
interface for each event class it handles in a custom way, those things
defaulting via the receiver interface class hierarchy, and, well,

I don't understand that, either. I thought directing control to unique
member functions for each unique event was handling it in a custom way.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
474,294
Messages
2,571,511
Members
48,206
Latest member
EpifaniaMc

Latest Threads

Top