ALright, pardon my messy code please. Below is my queue class. 
#include <iostream>
using namespace std; 
#ifndef QUEUE
#define QUEUE
/*----------------------------------------------------------------------------
Student Class
# Methods #
Student()               // default constructor
Student(string, int)    // constructor
display()               // out puts a student
# Data Members #
Name                    // string name
Id                      // int id
----------------------------------------------------------------------------*/
class Student { 
public: 
    Student() { } 
    Student(string iname, int iid) { 
        name = iname; 
        id = iid; 
    } 
    void display(ostream &out) const { 
        out << "Student Name: " << name << "\tStudent Id: " << id
            << "\tAddress: " << this << endl;  
    }  
private: 
    string name; 
    int id; 
}; 
// define a typedef of a pointer to a student. 
typedef Student * StudentPointer;
template <typename T> 
class Queue
{
public:
    /*------------------------------------------------------------------------
    Queue Default Constructor
    Preconditions: none
    Postconditions: assigns default values for front and back to 0
    description: constructs a default empty Queue. 
    ------------------------------------------------------------------------*/
    Queue() : myFront(0), myBack(0) {}
    /*------------------------------------------------------------------------
    Copy Constructor
    Preconditions: requres a reference to a value for which you are copying
    Postconditions: assigns a copy to the parent Queue. 
    description: Copys a queue and assigns it to the parent Queue. 
    ------------------------------------------------------------------------*/
    Queue(const T & q) { 
        myFront = myBack = 0; 
        if(!q.empty()) { 
            // copy the first node
            myFront = myBack = new Node(q.front()); 
            NodePointer qPtr = q.myFront->next; 
            while(qPtr != NULL) { 
                myBack->next = new Node(qPtr->data); 
                myBack = myBack->next; 
                qPtr = qPtr->next; 
            } 
        } 
    }
    /*------------------------------------------------------------------------
    Destructor
    Preconditions: none
    Postconditions: deallocates the dynamic memory for the Queue
    description: deletes the memory stored for a Queue. 
    ------------------------------------------------------------------------*/
    ~Queue() { 
        NodePointer prev = myFront, ptr; 
        while(prev != NULL) { 
            ptr = prev->next; 
            delete prev; 
            prev = ptr; 
        } 
    } 
    /*------------------------------------------------------------------------
    Empty()
    Preconditions: none
    Postconditions: returns a boolean value. 
    description: returns true/false based on if the queue is empty or full. 
    ------------------------------------------------------------------------*/
    bool empty() const { 
        return (myFront == NULL); 
    }
    /*------------------------------------------------------------------------
    Enqueue
    Preconditions: requires a constant reference
    Postconditions: allocates memory and appends a value at the end of a queue
    description: 
    ------------------------------------------------------------------------*/
    void enqueue(const T & value) {
        NodePointer newNodePtr = new Node(value); 
        if(empty()) { 
            myFront = myBack = newNodePtr; 
            newNodePtr->next = NULL; 
        } else { 
            myBack->next = newNodePtr; 
            myBack = newNodePtr; 
            newNodePtr->next = NULL; 
        } 
    }
    /*------------------------------------------------------------------------
    Display
    Preconditions: requires a reference of type ostream
    Postconditions: returns the ostream value (for chaining)
    description: outputs the contents of a queue. 
    ------------------------------------------------------------------------*/
    void display(ostream & out) const {
        NodePointer ptr; 
        ptr = myFront; 
        while(ptr != NULL) { 
            out << ptr->data << " "; 
            ptr = ptr->next; 
        } 
        out << endl; 
    }
    /*------------------------------------------------------------------------
    Front
    Preconditions: none
    Postconditions: returns a value of type T
    description: returns the first value in the parent Queue. 
    ------------------------------------------------------------------------*/
    T front() const {
       if ( !empty() ) 
          return (myFront->data);
       else
       {
          cerr << "*** Queue is empty -- returning garbage value ***\n";
          T * temp = new(T); 
          T garbage = * temp;
          delete temp; 
          return garbage;
       }
    }
    /*------------------------------------------------------------------------
    Dequeue
    Preconditions: none
    Postconditions: removes the first value in a queue
    ------------------------------------------------------------------------*/
    void dequeue() {
        if ( !empty() ) { 
            NodePointer ptr = myFront; 
            myFront = myFront->next; 
            delete ptr; 
            if(myFront == NULL) 
                myBack = NULL; 
        } else {
            cerr << "*** Queue is empty -- "
              "can't remove a value ***\n";
            exit(1);
        }
    }
    /*------------------------------------------------------------------------
    pverloaded = operator
    Preconditions: requires a constant reference
    Postconditions: returns a const type T
    description: this allows assigning of queues to queues
    ------------------------------------------------------------------------*/
    Queue<T> & operator=(const T &q) { 
    // make sure we arent reassigning ourself
    // e.g. thisQueue = thisQueue. 
        if(this != &q) { 
            this->~Queue(); 
            if(q.empty()) { 
                myFront = myBack = NULL; 
            } else { 
                myFront = myBack = new Node(q.front()); 
                NodePointer qPtr = q.myFront->next; 
                while(qPtr != NULL) { 
                    myBack->next = new Node(qPtr->data); 
                    myBack = myBack->next; 
                    qPtr = qPtr->next; 
                } 
            } 
        } 
        return *this; 
    }
private:
    class Node { 
    public: 
        T data; 
        Node * next; 
        Node(T value, Node * first = 0) : data(value),
                                          next(first) {}
    };  
    typedef Node * NodePointer; 
    NodePointer myFront,
               myBack,
               queueSize; 
}; 
/*------------------------------------------------------------------------
join
Preconditions: requires 2 queue values
Postconditions: appends queue2 to the end of queue1
description: this function joins 2 queues into 1. 
------------------------------------------------------------------------*/
template <typename T>
Queue<T> join(Queue<T> q1, Queue<T> q2) {
    Queue<T> q1Copy(q1), q2Copy(q2); 
    Queue<T> jQueue; 
    while(!q1Copy.empty()) { 
        jQueue.enqueue(q1Copy.front()); 
        q1Copy.dequeue(); 
    } 
    while(!q2Copy.empty()) { 
        jQueue.enqueue(q2Copy.front()); 
        q2Copy.dequeue(); 
    } 
    cout << jQueue << endl; 
    return jQueue;   
} 
/*----------------------------------------------------------------------------
Overloaded << operator 
Preconditions: requires a constant reference and a Queue of type T
Postconditions: returns the ostream (for chaining)
description: this function is overloaded for outputing a queue with <<
----------------------------------------------------------------------------*/
template <typename T>
ostream & operator<<(ostream &out, Queue<T> &s) { 
    s.display(out);  
    return out; 
} 
/*----------------------------------------------------------------------------
Overloaded << operator
Preconditions: requires a constant reference and a reference of type Student
Postconditions: none
description: this function is overloaded for outputing an object of type
             Student. 
----------------------------------------------------------------------------*/
ostream & operator<<(ostream &out, Student &s) { 
    s.display(out); 
}
/*----------------------------------------------------------------------------
Overloaded << operator
Preconditions: requires a constant reference and a reference of a pointer to
               a Student object. 
Postconditions: none
description: this function is overloaded for outputing pointers to Students
----------------------------------------------------------------------------*/
ostream & operator<<(ostream &out, StudentPointer &s) { 
    s->display(out); 
}
#endif
Now I'm having some issues with it. For one, when I add 0 to a queue and then I output the queue like so..
Queue<double> qdub; 
qdub.enqueue(0); 
cout << qdub << endl; 
That works, it will output 0. But for example, if I modify that queue in any way.. like.. assign it to a different queue.. 
Queue<double> qdub1; 
Queue<double> qdub2; 
qdub1.enqueue(0; 
qdub2 = qdub1; 
cout << qdub2 << endl; 
It will give me weird values for 0 like.. 7.86914e-316. 
Help on this would be much appreciated!