1

I have a queue.h file like the following.

Is it possible that I can access the head pointer of the queue from Main?

If yes, what should I do in main?

Since the head pointer is a class pointer, and its type is a protected nested class, I don't think I can access it from main.

Therefore, I try to create a function getHead() as public member. However, another problem comes, it is I am using template class. Please guide me how to solve this problem.

my header file:

#include <iostream>
#include <iomanip>
using namespace std;

class PCB
{
    public:
        int PID;
        string fileName;
};    

template<class T>
class myQueue
{
    protected:
        class Node
        {
            public:
                T info;
                Node *next;
                Node *prev;
        };

        Node *head;
        Node *tail;
        int count;

    public:
        void getHead(Node **tempHead);
};

template<class T>
void myQueue<T>::getHead(Node **tempHead)
{
    *tempHead = head;
}    
#endif 

my main is:

#include "myQueue.h"
#include <iostream>

int main()
{
    myQueue<PCB> queue;
    //How can I access the Head pointer of my Queue here?
    //queue.getHead(&tempHead);
    return 0;
}
πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190
Jecade
  • 13
  • 5
  • If you make Node a protected class, you will not be able to have Node* outside of the class. So make the class definition public and you can leave the members (like head, tail, count) still private. Then you could do Node* getHead() { return head; } – Gerriet May 27 '17 at 15:01
  • 1
    @Gerriet _"If you make Node a protected class, you will not be able to have Node* outside of the class"_ Wrong. See my answer. – πάντα ῥεῖ May 27 '17 at 15:04
  • 1
    Also note that "using namespace std" is considered bad practice in header files: https://stackoverflow.com/questions/1452721/why-is-using-namespace-std-considered-bad-practice – Gerriet May 27 '17 at 15:05
  • @πάντα ῥεῖ You are right, the distinction in the last paragraph of your answer is important. – Gerriet May 27 '17 at 15:16
  • The real question is, why do you want to do this? A class should encapsulate its data; exposing it to outsiders means that its contents cannot be trusted. That's almost always a bad idea. – Pete Becker May 27 '17 at 15:18
  • @PeteBecker There are a lot of cases where this makes sense. Think about them like opaque c handles. – πάντα ῥεῖ May 27 '17 at 15:23
  • @PeteBecker You are right, I should always encapsulate class' data. However, what I am trying to do is move the head item from queue 1, to queue 2. since I am using pointer in the queue, so I was thinking if i can do some violation and get the head pointer and use the head pointer of my queue 2 point to the 1st head pointer of queue 1. Do you have any idea if I try to moving items between two queues with pointer only? – Jecade May 27 '17 at 15:31
  • If you need to be able to swap data between two queues, your queue class should provide a mechanism for doing that. That's what encapsulation is all about: the class controls its data and what can be done with it. If you have to hack around with its data in order to do something then the design of the class is wrong. – Pete Becker May 27 '17 at 15:46
  • @πάνταῥεῖ Thank you very much. – Jecade May 27 '17 at 16:56
  • @PeteBecker I am very interested in the mechanism you were talking about. If you don't mind, could you give me more details? or one example? Let's say, I have Queue 1, data in Queue 1 is [0, 1, 2, 3] Queue 2 is empty queue. Now if I need to remove 0 from Queue 1, and add to Queue 2. How are you going to create your queue file with pointer base only? – Jecade May 27 '17 at 17:08

1 Answers1

2

To acess myQueue::Node from outside the class you need to rewrite your getter function a bit:

template<class T>
myQueue<T>::Node* myQueue<T>::getHead()
{
    return head;
}

Then you can use it in main() like this

auto head = queue.getHead();

Note that the usage of auto is important in this case. You still cannot declare any variable of type myQueue<T>::Node or myQueue<T>::Node** outside of myQueue<T>, but you can use auto variables to hold these types.

πάντα ῥεῖ
  • 1
  • 13
  • 116
  • 190