Some of the previous videos and reading have covered the implications of an object owning some dynamically allocated memory. Mainly, what I’m referring to here is the need for a copy constructor, overloaded assignment operator, and destructor in a class that contains any dynamically allocated memory. That’s all important stuff. Know it, learn it, love it.
But what about the dynamic allocation of objects themselves – how does it work and what are the implications. I’m glad you asked. Dynamically allocating an object is just like dynamically allocating anything else. You use the keyword new to ask the memory manager to find and reserve some memory big enough for what you’re trying to allocate, and if successful that memory allocator sends you back a pointer to the memory.
For discussions, let’s assume we have the following class:
class Player { private: int id; string name; int level; public: Player(); void nextLevel(); int getLevel(); string getName(); void setName(string newName); };
So, if we wanted to dynamically allocate a single Player object, we could do something like the following:
Player* nextPlayer = new Player;
Or if we wanted to dynamically allocate an array of Player objects, we could do something like this:
Player* currentPlayers = new Player[10];
There are a couple couple things to keep in mind when you’re working with pointers to objects.
- Dynamically allocating an object still causes the object to be instantiated, thus calling the constructor. However, simply creating a pointer variable to a user-defined type (a class that the programmer creates) doesn’t actually create any objects. So, Player* p; doesn’t instantiate any objects.
- Related to #1, you need to make sure you have a constructor that is compatible with your dynamic allocation statement. Assume that the Player class only had 1 constructor that took an integer representing the player’s id. If that were the case, then there would be no default constructor. Therefore, the statement
Player* nextPlayer = new Player;
wouldn’t be able to compile because there would be no matching constructor. Similarly, the allocation of the array in
Player* currentPlayers = new Player[10];
wouldn’t compile for the same reasons.
- This is a biggie w.r.t syntax: when accessing a member of a class (such as a member function) from a pointer to an object, you need to use a different operator than the ‘.’. The operator you use is ‘->’ (dash followed by greater-than sign, no space in between). This indicates that the identifier on the right hand side of the operator is a pointer to an object rather than an object itself. Consider this example:
int main() { Player* p = new Player; p -> setName(string("Coffee Nut")); cout << "Player: " << p->getName() << "\tLevel: " << p->getLevel() << endl; return 0; }
Note that using the -> operator is the same as dereferencing an pointer to an object then using the . operator. So from the declaration and initialization of p above, p -> getName(); is equivalent to (*p)->getName();
The concept of pointers to objects is very important when attempting to implement polymorphism in C++.
Peace, love, c++!
Speak Your Mind