1) Don't overload the destructor if it doesn't do anything productive. It's common practice to use the destructor for the deallocation of reserved memory.
2) I see a call to new but no call to delete.
3) Use code tags.
As for your problem, which isn't a problem, s evaluates to the address it points to, which is null (initialisation stage of s), which is effectively the same as 0; thus, std::cout yields 0.
Because here you are creating a stack pointer s which points to the value of 0, not to any specific address. When you pass your stack pointer from main to newStack, newStack then assigns the passed pointer to a random place[an address] in memory large enough to hold a Stack object. [this is what happens when you use the new operator]
What I am confused here is that I am pssing a pointer to a function where a new memory is assigned. So after calling this function, the variable s should have a pointer to that address, right?
Yes. new yields a pointer to the allocated memory. s is then assigned to the address where the allocated memory resides. This is called transferring memory ownership, which means giving allocated memory to another pointer.
I know how to fix this and how to implement more elgant way, but what I don't understand from this simple excise is the concept of passing by reference that I have understood so far.
Passing a pointer to a function should basically be able to change the value of that pointer pointing to. So if I assign a new memory to that passed pointer, I should be able to have a correct pointing address.
Am I missing any fundamental basic concept here?
As you said, "the pointer itself declared as a parameter is a local object of the function". If this is true, then how can you achieve "pass by reference to the fucntion"?