Presentation is loading. Please wait.

Presentation is loading. Please wait.

Beginning C++ Through Game Programming, Second Edition by Michael Dawson.

Similar presentations


Presentation on theme: "Beginning C++ Through Game Programming, Second Edition by Michael Dawson."— Presentation transcript:

1 Beginning C++ Through Game Programming, Second Edition by Michael Dawson

2 Chapter 9 Advanced Classes and Dynamic Memory: Game Lobby

3 Objectives Combine objects Use friend functions Overload operators Dynamically allocate and free memory Avoid memory leaks Produce deep copies of objects

4 Aggregation Game objects often composed of other objects –Drag racer: body, four tires, an engine Other times, see an object as a collection of related objects –Zoo as a collection of animals Can mimic these kinds of relationships among objects in OOP using aggregation

5 Using Object Data Members A data member that's an object itself Has a relationship A Critter object can have an attribute m_Name that is a string object

6 Critter Class class Critter { public: Critter(const string& name = ""); string GetName() const; private: string m_Name; }; Critter::Critter(const string& name): m_Name(name) {} inline string Critter::GetName() const { return m_Name; }

7 Container Data Members You can also use containers as data members for your objects A Farm object has a single data member that's a vector for Critter objects

8 Farm Class class Farm { public: Farm(int spaces = 1); void Add(const Critter& aCritter); void RollCall() const; private: vector m_Critters; };

9 Farm Class (cont.) Farm::Farm(int spaces) { m_Critters.reserve(spaces); } void Farm::Add(const Critter& aCritter) { m_Critters.push_back(aCritter); } void Farm::RollCall() const { for (vector ::const_iterator iter = m_Critters.begin(); iter != m_Critters.end(); ++iter) cout GetName() << " here.\n"; }

10 Using Critter and Farm int main() { Critter crit("Poochie"); cout << "Critter's name:" << crit.GetName() cout << "\nCreating critter farm.\n"; Farm myFarm(3); cout << "\nAdding three critters to farm.\n"; myFarm.Add(Critter("Moe")); myFarm.Add(Critter("Larry")); myFarm.Add(Critter("Curly")); cout << "\nCalling Roll...\n"; myFarm.RollCall(); return 0; }

11 Friend Functions Friend functions have complete access to any member of a class Specify function is friend of a class with friend before function prototype inside class definition In a Critter class: friend void Peek(const Critter& aCritter); Peek() can access any member of a Critter object Outside of Critter class definition, define global function Peek() : void Peek(const Critter& aCritter) { cout << aCritter.m_Name << endl; } Peek() can access private member m_Name of a Critter object

12 Overloading Operators Give meaning to built-in operators used with new types that you define Overload the << operator so it can work with Critter objects Can send Critter object << to cout Outside a Critter class, define a global function that overloads << operator ostream& operator<<(ostream& os, const Critter& aCritter) { os << "Critter Object - "; os << "m_Name: " << aCritter.m_Name; return os; } Function can directly access the private data member m_Name of a Critter object because function is a friend of the Critter class friend ostream& operator<<(ostream& os, const Critter& aCritter);

13 Dynamically Allocating Memory Local variables live on the stack Local variables don't persist beyond function in which declared Heap memory persists until programmer frees it Dynamic heap memory offers efficiency –Use only memory needed, free when done –Access memory even after a function ends (without having to return a copy of the object)

14 The new Operator Allocates memory on the heap and returns its address Use new followed by the type of value int* pHeap = new int; new int allocates memory on the heap for one int and returns its address int* pHeap, declares a local pointer, pHeap, which points to the newly allocated chunk of memory on the heap Can initialize memory on the heap at the same time you allocate it int* pHeap = new int(10);

15 Memory on the Heap Persists int* intOnHeap() { int* pTemp = new int(20); return pTemp; } Can access heap memory from another function int* pHeap2 = intOnHeap();

16 The delete Operator Memory on the heap must be explicitly freed delete pHeap; Memory on heap pointed to by pHeap is returned to the heap for future use Good rule of thumb—every new should have a corresponding delete

17 delete Pitfalls Freeing memory on the heap with delete does not alter pointers to the heap When calling delete on a pointer, potential problem of dangling pointer Never dereference dangling pointers Can assign 0 to them, as in delete pHeap; pHeap = 0; Or immediately assign dangling pointer valid memory address

18 Memory Leak 1 Allocate memory on heap but have no way to free Large enough leak, a program runs out of memory and crashes void leak1() { int* drip1 = new int(30); } No way to free the allocated memory on heap that stores 30

19 Memory Leak 1 (cont.) To avoid –delete drip1 in leak1() function –OR return copy of drip1 and free memory later

20 Memory Leak 2 void leak2() { int* drip2 = new int(50); drip2 = new int(100); delete drip2; } Assigning drip2 address of memory on the heap that stores the 100 leaks memory on the heap that stores 50

21 Memory Leak 2 (cont.) To avoid leak, delete drip2 before assigning new memory address to it

22 Declaring Data Members on the Heap Given the constructor of a Critter class Critter::Critter(const string& name, int age) { cout << "Constructor called\n"; m_pName = new string(name); m_Age = age; } Each Critter object has data member, m_pName, that's a pointer to memory on the heap

23 Destructors Member function that’s called just before an object is destroyed Most often used for cleanup Must have the name of the class preceded by a tilde ( ~ ) character No parameters and no return value If you don’t write a destructor of your own, complier will supply a default destructor

24 Destructor Example If necessary to clean up memory on the heap—default constructor won't do ~Critter() { cout << "Destructor called.\n"; delete m_pName; } When class allocates memory on the heap, write a destructor that frees that memory

25 Copy Constructors Sometimes an object is copied automatically Copying is done by a special member function called the copy constructor Occurs when an object is –Passed by value to a function –Returned from a function –Initialized to another object through an initializer –Provided as a single argument to the object’s constructor

26 Default Copy Constructor Default copy constructor is supplied if you don’t write your own Copies the value of each data member to data members of the same name in the new object—shallow copy For simple classes, default copy constructor is usually fine For classes with a data member that points to value on the heap, usually write your own copy constructor

27 Default Copy Constructor Pitfalls Default copy constructor creates shallow copies Potential problem if object has data member on the heap

28 Default Copy Constructor Pitfalls (cont.) Deleting shallow copy leaves original object with dangling pointer

29 Copy Constructor Copy constructor must have the same name as the class Returns no value, but accepts a reference to an object of the class— the object that needs to be copied Reference is almost always made a constant reference to protect the original object from being changed during the copy process

30 Copy Constructor Example Following allocates separate memory on the heap for the name of the new Critter object //copy constructor definition Critter::Critter(const Critter& c) { cout << "Copy Constructor called\n"; m_pName = new string(*(c.m_pName)); m_Age = c.m_Age; }

31 Copy Constructor Example - Continued Copy constructor creates deep copy When copy of object is destroyed, original is unaffected

32 Overloading the Assignment Operator When both sides of an assignment statement are objects of the same class, the class’ assignment operator member function is called A default assignment operator member function is supplied for you if you don’t write one of your own Default assignment operator provides only member- wise duplication For simple classes, the default assignment operator is usually fine When you have a class with a data member that points to a value on the heap, you usually provide an overloaded assignment operator of your own; if you don’t, you’ll end up with shallow copies of objects when assigning one object to another.

33 Overloading the Assignment Operator Critter& Critter::operator=(const Critter& c) //overloaded assignment op def { cout << "Overloaded Assignment Operator\n"; if (this != &c) { delete m_pName; m_pName = new string(*(c.m_pName)); m_Age = c.m_Age; } return *this; }

34 Summary Aggregation is the combining of objects so that one is part of another Friend functions have complete access to any member of a class Operator overloading allows you to define new meanings for built-in operators as they relate to objects of your own classes The stack is an area of memory that is automatically managed for you and is used for local variables The heap is an area of memory that the programmer can use to allocate and free memory

35 Summary (cont.) The new operator allocates memory on the heap and returns its address The delete operator frees memory on the heap that was previously allocated A dangling pointer points to an invalid memory location Dereferencing or deleting a dangling pointer can cause your program to crash A memory leak is an error in which memory that has been allocated becomes inaccessible and can no longer be freed

36 Summary (cont.) A destructor is a member function that’s called just before an object is destroyed If you don’t write a destructor of your own, the complier will supply a default destructor for you The copy constructor is a member function that’s invoked when an automatic copy of an object is made A default copy constructor is supplied for a class if you don’t write one of your own The default copy constructor simply copies the value of each data member to data members with the same names in the copy, producing a shallow copy

37 Summary (cont.) A deep copy is a copy of an object that has no chunks of memory in common with the original A default assignment operator member function, which produces a shallow copy, is supplied for you if you don’t write one of your own


Download ppt "Beginning C++ Through Game Programming, Second Edition by Michael Dawson."

Similar presentations


Ads by Google