A pointer refers to the memory address of an object. It is not the object itself. So manipulating a pointer literally involves changing the memory address it refers to. In order to work with the actual value pointed to, you have to use certain syntax.
The advantage of pointers has to do with object lifetime and dynamic memory allocation. Objects declared as "MyClass obj;" are created on the memory
stack, which is very fast and efficient; however, once that object goes out of scope (the block it was declared in closes), it is deconstructed, popped off the stack, and is no longer valid. Pointers, however,
generally are used to keep track of objects created on the memory
heap, which is a big block of memory reserved for dynamic allocation. Creating an object with "new" ("new MyClass;") puts that object on the heap and returns a pointer to the memory block. The object stays on the heap forever until your program exits or until you use the "delete" command on a pointer that points to the object's memory location. The heap is slower to allocate and deallocate since the OS has to search through that giant memory area to find a spot big enough for your object (whereas the stack just pushes your object on top and moves on). So why would we ever use the heap?
Here's one example. Let's say you're writing a function that asks the user for his name and returns that as a std::string:
Code:
std::string getUserName() {
std::string name;
cout << "What is your name? ";
cin >> name;
return name;
}
There's a few things bad about this. First, you're returning the string by VALUE, which means that the entire string that you just scanned is going to be duplicated into a new string object and returned to the calling function. What if your user types in a 1000-char name? Now you've blown another 1K of memory by copying that string just to return it. A better method would be to return a
pointer to the string, which would allow the calling function to follow the pointer to access the original variable. You wouldn't be constructing another string object, just a 4-byte pointer to the existing one:
Code:
std::string *getUserName() {
std::string name;
cout << "What is your name? ";
cin >> name;
return &name;
}
Now the caller can say... "std::string *username = getUserName(); count << *username;" to work with the original string instead of a duplicate. HOWEVER, we still have a problem. Because the "name" variable in getUserName() was declared locally, it went on the STACK, and once the function terminated, that variable was POPPED off the stack. So the pointer return by getUserName() points to a section of memory that is no longer valid. Sure, the data for the string is still there, since it's likely no one else has messed with the stack yet. But you'll run into problems if you continue using that pointer later in the program, and they might be very subtle (like a few missing characters with no explanation). Or your program could blow up with a segfault if you're lucky.
So the proper way to do that function would be:
Code:
std::string *getUserName() {
std::string *name = new std::string;
cout << "What is your name? ";
cin >> *name;
return name;
}
So that's the most general reason why we use pointers and the heap: to pass around references to objects that stay in existence even when they fall out of scope.
NOTE TO C++ GURUS: yes, I know that std::string uses a char pointer internally and that duplicating a std::string wouldn't duplicate the char buffer... I was just making an example
.