class template / want Node to store physical object not just pointer to it

the more i learn the more fundamentals i forget, at least i think. maybe i am just a stupid idiot. this is really ticking me off as i hate it when i fail at something.

i have a queue template that should hold a a queue of worker pointers. the workers are based on public multiple inheritance with virtual base classes. the worker class children are waiter, singer, & singing waiter, where singing waiter inherits from waiter and singer.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
template <typename T>
class Queue
{
private:
    struct Node {T item; struct Node * next;};
    enum {Q_SIZE = 10};
    // private class members
    Node * front; // pointer to front of node
    Node * rear; // pointer to rear of node
    int items; // current number if items in queue
    const int qsize; // max number of items in queue
    // preemptive definitions to prevent public copying
    Queue(const Queue & q) : qsize(0) {}
    Queue & operator=(const Queue & q) {return *this;}
public:
    Queue(int qs = Q_SIZE); // create queue with a qs limit
    ~Queue();
    bool isempty() const;
    bool isfull() const;
    int queuecount() const;
    bool enqueue(const T & item); // insert item to end
    bool dequeue(T & item); // remove item from front
};


an instantiated template would be called by Queue<Worker *> tp;

since the queue is a container i want the actual worker object to be held inside the node using the heap like, item = new<T>;. i cannot figure out how to get the node to do this within it's nested decleration. the compiler is objecting.

i can do this in main();

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
Worker * lolas[SIZE];

    int ct;
    for (ct = 0; ct < SIZE; ct++)
    {
        char choice;
        cout << "Enter the employee category:\n"
            << "w: waiter s: singer  "
            << "t: singing waiter   q: quit\n";
        cin >> choice;
        while (strchr("wstq", choice) == NULL)
        {
            cout << "Please enter a, w, s, t, or q: ";
            cin >> choice;
        }
        if (choice == 'q')
            break;
        switch(choice)
        {
            case 'w':   lolas[ct] = new Waiter;
                        break;
            case 's':   lolas[ct] = new Singer;
                        break;
            case 't':   lolas[ct] = new SingingWaiter;
                        break;
        }
        cin.get();
        lolas[ct]->Set();


but that just creates the worker pointer array independentenly. i can of course copy the worker type pointers into the queue nodes but why not use the actal queue (since its a container) to do this instead of having multiple containers(Worker *[array] and Queue<Worker *>array, for example) to hold the same object? main() also prints the data for the workers using that same array.

maybe i am thinking this too much. i actually think what i am expressing is a symptom of a human brain being fried.
Last edited on
If I understand correctly, you have a base class: Worker, from that Waiter and Singer are public virtual derived from worker. Then you have class SingingWaiter which publicly derives from both Waiter and Singer?

I don't know how your bool enqueue(const T & item); is implemented but this is where your work will be if all the above statements are true and correct.

Something like this.. but not limited to this code:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
bool enqueue(const T & item)
{
   if(!front)
   {
       //Handle case where front is NULL, empty w/e you want to call it
   }else
   {
        //Sample code where inserting and front is Not null... and excluding back for simplicity...
	Node * pNewNode = new Node(item);
	Node * current = front;
	while(current->next)
           current = current->next;
	current->next = pNewNode ;
	//...	
   }
    //other stuff
}



You will notice in this code, the Node constructor takes in a parameter of type const &T, you need to add this to your struct to do what you want to do.
Last edited on
thanks for the reply. yes the multiple inheritance is setup exactly as you state and everything works. it's just that creating the actual object in the heap via inside the node method is something that i am trying to understand. the book has not covered this, from what i can recall.

thanks for the suggestion. i know i read it somewhere in the book about doing something like "int * something = new something(and_adding_an_argument)" but honestly it must only have talked about this briefly just once and completely forgot about it, reading through 1000 pages so far.

my original enque is;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
template <typename T>
bool Queue<T>::enqueue(const T & item)
{
    if (isfull())
        return false;
    Node * add = new Node; //  create node
    // on failure new throws std:bad alloc exception
    add->item = item; // set node pointers
    add->next = NULL; // or nullptr;
    items++;
    if (front == NULL) // if queue is empty
        front = add; // place item at front
    else
        rear->next = add; // else place at rear
    rear = add; // have rear point to new node
    return true;
}


i changed the Node * add = new Node; to Node * add = new Node(item); like you suggested and also adjusted the struct node by adding a constructor to at the end of the line like this; struct Node {T item; struct Node * next; Node(const T & go) {item = new T;}}; and the code compiled finally.

but when in main i attempt to bypass the pointer array and try to create the objects inside the node but fails.

1
2
3
4
5
switch(choice)
        {
            case 'w':   test.enqueue(new Waiter); //I ADDED THIS
                             //lolas[ct] = new Waiter; // COMMENTED THIS OUT
                             break;


error: cannot convert 'Worker**' to 'Worker*' in assignment|
Topic archived. No new replies allowed.