1 CS 103 Unit 10 Slides C++ Classes Mark Redekopp
2 Object-Oriented Programming • Model the application/software as a set of objects that interact with each other • Objects fuse data (i.e. variables) and functions (a.k.a methods) that operate on that data into one item (i.e. object) – Like structs but now with associated functions/methods • Objects become the primary method of encapsulation and abstraction – Encapsulation • Hiding of data and implementation details (i.e. make software modular) • Only expose a well-defined interface to anyone wanting to use our object – Abstraction • How we decompose the problem and think about our design rather than the actual code
3 Objects • Objects contain: – Data members • Data needed to model the object and track its state/operation (just like structs) – Methods/Functions • Code that operates on the object, modifies it, etc. • Example: Deck of cards – Data members: • Array of 52 entries (one for each card) indicating their ordering • Top index – Methods/Functions • Shuffle(), Cut(), Get_top_card()
4 C++ Classes #include <iostream> using namespaces std; class Deck { Classes are the programming construct used • public: to define objects, their data members, and Deck(); // Constructor int get_top_card(); methods/functions private: int cards[52]; Similar idea to structs • int top_index; }; Steps: • // member function implementation – Define the class’ data members and Deck::Deck() { function/method prototypes poker.cpp for(int i=0; i < 52; i++) – Write the methods cards[i] = i; } – Instantiate/Declare object variables and use int Deck::get_top_card() { them by calling their methods return cards[top_index++]; Terminology: } • // Main application int main(int argc, char *argv[]) { – Class = Definition/Blueprint of an object Deck d; – Object = Instance of the class, actual int hand[5]; d.shuffle(); allocation of memory, variable, etc. d.cut(); for(int i=0; i < 5; i++){ hand[i] = d.get_top_card(); } ...
5 C++ Classes class Deck { public: Deck(); // Constructor Classes are the programming construct used • ~Deck(); // Destructor void shuffle(); to define objects, their data members, and deck.h void cut(); methods/functions int get_top_card(); private: Similar idea to structs • int cards[52]; int top_index; Steps: • }; – Define the class’ data members and #include<iostream> deck.cpp function/method prototypes (usually in a #include “deck.h” separate header file) // Code for each prototyped method – Write the methods (usually in a separate #include<iostream> .cpp file) #include “deck.h” – Instantiate/Declare object variables and use int main(int argc, char *argv[]) { them by calling their methods poker.cpp Deck d; int hand[5]; Terminology: • d.shuffle(); – Class = Definition/Blueprint of an object d.cut(); for(int i=0; i < 5; i++){ – Object = Instance of the class, actual hand[i] = d.get_top_card(); } allocation of memory, variable, etc. }
6 Class Definition class Deck { class name { … }; • public: Deck(); // Constructor Each function or data member can be classified • ~Deck(); // Destructor void shuffle(); as public, private, or protected deck.h void cut(); These classifications support encapsulation by – int get_top_card(); private: allowing data/method members to be int cards[52]; inaccessible to code that is not a part of the class int top_index; (i.e. only accessible from within a public class }; method) #include<iostream> Ensure that no other programmer writes code – deck.cpp #include “deck.h” that uses or modifies your object in an unintended way // Code for each prototyped method Private : Can call or access only by – #include<iostream> methods/functions that are part of that class #include “deck.h” – Public : Can call or access by any other code int main(int argc, char *argv[]) { poker.cpp – Protected : More on this later Deck d; int hand[5]; Everything private by default so you must • d.shuffle(); use “public:” to make things visible d.cut(); d.cards[0] = ACE; //won’t compile • Make the interface public and the d.top_index = 5; //won’t compile guts/inner-workings private }
7 Constructors / Destructors class Deck { public: deck.h Deck(); // Constructor • Constructor is a function of the same name as ~Deck(); // Destructor the class itself ... }; It is called automatically when the object is – created (either when declared or when allocated #include<iostream> #include “deck.h” via ‘new’) Use to initialize your object (data members) to – Deck::Deck() { desired initial state top_index = 0; for(int i=0; i < 52; i++){ deck.cpp – Returns nothing cards[i] = i; } Destructor is a function of the same name • } as class itself with a ‘~’ in front Deck::~Deck() { Called automatically when object goes out of – } scope (i.e. when it is deallocated by ‘delete’ or #include<iostream> when scope completes) #include “deck.h” poker.cpp Use to free/delete any memory allocated by the – int main(int argc, char *argv[]) { object Deck d; // Deck() is called ... – Returns nothing return 1; – [Note: Currently we do not have occasion to use // ~Deck() is called since destructors; we will see reasons later on in the // function is done course] }
8 Writing Member Functions class Deck { public: deck.h Deck(); // Constructor When writing member functions, the • ~Deck(); // Destructor ... compiler somehow needs to know that }; the function is a member of a particular #include<iostream> class and that the function has inherent #include “deck.h” access to data members (w/o declaring Deck::Deck() { top_index = 0; them). Thus we must ‘scope’ our for(int i=0; i < 52; i++){ functions cards[i] = i; } Include the name of the class followed by • } Deck::~Deck() ‘::’ just before name of function { deck.cpp } This allows the compiler to check access • to private/public variables void Deck::shuffle() { Without the scope operator [i.e. void shuffle() – cut(); //calls cut() for this object rather than void Deck::shuffle() ] the compiler ... } would think that the function is some outside int Deck::get_top_card() function (not a member of Deck) and thus { generate an error when it tried to access the top_index++; data members (i.e. cards array and top_index). return cards[top_index-1]; }
9 Calling Member Functions cards[52] 0 1 2 3 4 5 6 7 d1 • Member functions are called by top_index 0 preceding their name with the cards[52] d2 0 1 2 3 4 5 6 7 specific object that it should top_index operate on 0 • d1.shuffle() indicates the code #include<iostream> #include “deck.h” of shuffle() should be operating int main(int argc, char *argv[]) { implicitly on d1’s data member Deck d1, d2; int hand[5]; vs. d2 or any other Deck object d1.shuffle(); // not Deck.shuffle() or // shuffle(d1), etc. for(int i=0; i < 5; i++){ hand[i] = d1.get_top_card(); } } cards[52] 41 27 8 39 25 4 11 17 d1 top_index 1
10 Calling Member Functions #include<iostream> • Within a member function we #include “deck.h” can just call other member int main(int argc, char *argv[]) { Deck d1, d2; poker.cpp functions directly. int hand[5]; d1.shuffle(); d1 is implicitly ... d1’s data will be modified passed to shuffle() } (shuffled and cut) #include<iostream> cards[52] 41 27 8 39 25 4 11 17 #include “deck.h” d1 void Deck::shuffle() top_index 0 { cut(); // calls cut() // for this object for(i=0; i < 52; i++){ cards[52] d2 0 1 2 3 4 5 6 7 int r = rand() % (52-i); deck.cpp int temp = cards[r]; top_index 0 cards[r] = cards[i]; cards[i] = temp; } Since shuffle was implicitly } working on d1’s data, d1 is void Deck::cut() again implicitly passed to cut() { // swap 1 st half of deck w/ 2 nd }
11 Exercises • In-class Exercises
12 Class Pointers cards[52] 0 1 2 3 4 5 6 7 d1 • Can declare pointers to these top_index 0 new class types cards[52] d2 0 1 2 3 4 5 6 7 • Use ‘->’ operator to access top_index 0 member functions or data #include<iostream> #include “deck.h” int main(int argc, char *argv[]) { Deck *d1; int hand[5]; d1 = new Deck; d1->shuffle(); for(int i=0; i < 5; i++){ hand[i] = d1->get_top_card(); } } cards[52] 41 27 8 39 25 4 11 17 d1 top_index 5
13 Multiple Constructors class Student { • Can have multiple public: Student(); // Constructor 1 constructors with Student(string name, int id, double gpa); // Constructor 2 deck.h different argument lists ~Student(); // Destructor string get_name(); int get_id(); double get_gpa(); void set_name(string name); void set_id(int id); void set_gpa(double gpa); #include<iostream> private: #include “deck.h” string _name; int _id; int main() double _gpa; { }; Student s1; // calls Constructor 1 string myname; Student::Student() cin >> myname; { s1.set_name(myname); _name = “”, _id = 0; _gpa = 2.0; deck.cpp s1.set_id(214952); } s1.set_gpa(3.67); Student::Student(string name, int id, double Student s2(myname, 32421, 4.0); gpa) // calls Constructor 2 { _name = name; _id = id; _gpa = gpa; } }
Recommend
More recommend