Help with a Queue template class...

Started by
12 comments, last by ZealousEngine 17 years ago
I have a template queue classe..

template < class T, size_t N > class LocklessQueue; 
Now I want to create a STATIC queue that both a reader thread and writer thread can access. No problem right? Just inherit the static class to both 'reader' and 'writer' thread. The problem is, if I do that, both the reader and writer thread have unrestricted access to the queue object (the reader can write, when it should only be able to read, ect...). So I decided to make a little 'QueReader/QueWriter' wrapper class, that would restrict access to the base LocklessQueue class...

template < class T, size_t N > class QueReader { 

   public: 
      Reader( LocklessQueue<T,N>* ptr ) : mQuePtr(ptr) {} 

      //read functions go here, they use the mQuePtr 

   private: 
      LocklessQueue<T,N>* mQuePtr; 

}; 
Seems good so far, right? So to recap, the idea is we start with a static base class LocklessQueue, from that we sub class a 'QueReader' (which restricts access to the LocklessQueue), then we inherit THAT 'QueReader' class to the 'reader thread' (so it can only READ from the que, not write to it). Heres what I got so far...

template < class T, size_t N > class QueReader { 

   public: 
      QueReader( LQ::LocklessQueue<T,N>* ptr ) : mQuePtr(ptr) {} 

      //read functions go here 

   private: 
      LQ::LocklessQueue<T,N>* mQuePtr; 

}; 

class SysNameQue { 

   public: 
      static LQ::LocklessQueue< int, 4 > que; 

}; 

class SysNameQueReader : public SysNameQue { 

   public: 
      QueReader< int, 4 > mMyReader( static &que ); 
       
}; 
...I get the following error...

c:\zealengine\application\systems\template\sysnameque.h(30) : warning C4042: 'que' : has bad storage class 
c:\zealengine\application\systems\template\sysnameque.h(30) : error C4430: missing type specifier - int assumed. Note: C++ does not support default-int 
Im guessing im misusing static in some way? Thanks in advance for any info!
Advertisement
what's

QueReader< int, 4 > mMyReader( static &que );

supposed to be? a variable declaration? that's not the right way to do a variable declaration and initialization. use the constructor to initialize it (if it is a variable declaration).
Yes im trying to declare a 'QueReader' object, and it needs to be initialised with the type and size from the static base class LocklessQueue.

I dont think that 'static' is supposed to be there, but I tried...

QueReader< int, 4 > mMyReader( &que );

And it complained that que wasnt found (or something like that).

So to sum up, when I inherit a static object (the lockless queue object) why cant I use that inherited object to initialise/declare a member of the subclass?
Quote:Original post by ZealousEngine
So to sum up, when I inherit a static object (the lockless queue object) why cant I use that inherited object to initialise/declare a member of the subclass?


You can. You need to initialize a member variable in the constructor's initializer list, not in the class's declaration. Object members get values on object construction, not during class declaration.

--smw

Stephen M. Webb
Professional Free Software Developer

But with a class like the one ive shown above, how can I initialise it in a constructor? Correct me if im wrong, but cant a template class like this only be declared/initialised at the same time?

Youre right I CAN create the object in the constructor, but it needs to be DECLARED as a member first.. I dont see how to do that..
On a somewhat unrelated note, I'm curious about your LocklessQueue class: how do you support locklessness in a concurrent environment? You mentioned "reader" and "writer" threads in the singular; are you simply exploiting the fact that you only have a single R and W thread? Or, perhaps, I've completely misinterpreted and the name only indicates the queue must be accessed via some form of external locking.

My apologies for mildly hijacking the thread but I've been toying with various concurrency constructs recently and I'm interested in other implementations. Plus I figured the topic was at least related.
Yup thats right, two threads can run in parallel because the 'writer' can only push the head, and the 'reader' can only pop the tail. It works great.

If I could just get this damn wrapper to work, it would be fool proof too..
I think maybe im making this more difficult than it needs to be...

Im gonna try a solution with virtual functions...
1. Initializer lists!!!!!

class SysNameQueReader : public SysNameQue { public:    SysNameQueReader():     mMyReader(&que) // calls mMyReaders constructor with &que    { }    QueReader< int, 4 > mMyReader; };


2. Your design violates The Liskov Substitution Principle. (I wouldnt really worry about it to much if your still relativly new to programming but its still something to take note of)
What happens when you try to pop from an empty queue?

This topic is closed to new replies.

Advertisement