C++ Stack using template
If you provide a destructor you should handle copying and assigning. In other words follow the Rule of 3 (or 5 if you care about move semantics). You can also disallow them but then there should be move constructor and assignment.

Otherwise you will get in trouble with double freeing when calling a function void foo(Stack&lt;int&gt; s).



empty() doesn't change the stack. So it should also be const.

Consider adding a peek() method that returns a reference to the top value of the stack (with const and non-const version).

T&amp; peek()
{
    return topNode-&gt;data;
}

const T&amp; peek() const
{
    return topNode-&gt;data;
}


The reason for using the reference is to avoid a unnecessary copy. 



Having a print method interacting with the console is not a good idea. What if you want to show the contents in a gui instead?

Instead add iterators to be able to inspect what is on the stack without having to capture the output that print() generates.