I have looked at some previous posts and changed my code accordingly. Do you have some suggestions about my current code? 

Here are my specific questions:

1. What should `top()` return if the stack is empty?
2. Why it’s better to use `size_t` for count?
3. I didn’t use `new` to create the stack in `main()`. Do I need to call the destructor? If no, why? If yes, how should I do it?
4. According to the rule of three, how will I define the assignment operator for stack? Can you give one example?
5. I feel I have some misunderstanding about `private`. I put `top_node` in the private section, but why I am able to access `top_node` in the copy constructor?

The following code compiles and runs.

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

template<class T>
class MyStack{
public:
    MyStack(): top_node(nullptr), count(0){};

    MyStack(MyStack& st){
        top_node = new Node(st.top());
        Node* temp = st.top_node->next;
        Node* pre = top_node;
        while(temp){
            Node* cur = new Node(temp->val);
            pre->next = cur;
            temp = temp->next;
        }
        count = st.size();
    }

    void push(T item){
        Node* temp = new Node(item);
        if(empty()){
            top_node = temp;
        }else{
            temp->next = top_node;
            top_node = temp;
        }
        count++;    
    }

    void pop(){
        if(empty()){
            cout<<"Nothing to pop!"<<endl;
            return;
        }
        Node* temp = top_node;
        top_node = temp->next;
        delete temp;
    }

    int top() const{
        if(empty()){
            cout<<"Nothing to top!"<<endl;
            return -1;
        }
        return top_node->val;
    }

    size_t size() const{
        return count;
    }

    void print() const{
        Node* temp = top_node;
        while(temp){
            cout<<temp->val<<" ";
            temp = temp->next;
        }
        cout<<endl;
    }

    bool empty() const{
        return count==0;
    }

    ~MyStack(){
        Node* temp = top_node;
        while(temp){
            Node* t = temp;
            temp = temp->next;
            delete t;
        }
        top_node = nullptr;
    }

private:
    struct Node{
        T val;
        Node* next;
        Node(T x): val(x), next(nullptr){};
    };
    Node* top_node;
    size_t count;

};

int main(){

    MyStack<char> sasa;
    cout<<"default top: "<<sasa.top()<<endl;
    cout<<"default count: "<<sasa.size()<<endl;

    sasa.pop();
    sasa.push('a');
    sasa.push('p');
    sasa.push('p');
    sasa.print();
    sasa.top();
    cout<<"The current size is "<<sasa.size()<<endl;
    sasa.pop();
    sasa.print();
    cout<<"if empty: "<<sasa.empty()<<endl;

    MyStack<char> sec(sasa);
    sec.print();

    return 0;
}

```