Upload
martha-greer
View
213
Download
0
Embed Size (px)
Citation preview
Classes
Joe Meehean
Complex Data Types• What if we need more complex data types?• not simple primitives like ints, float, and chars• data types that are made of other smaller data types
• e.g., Song• name• album• artist• duration
• Do we need to store all these things separately?• Pass 4 parameters to each Song function?
2
C++ Classes• Classes• a set of data types stored in one object• a set of functions that manipulate that data
• Glue data together into more complex , abstract data types• Member data/variables: variable contained in a class
• Data is not independent of functions that modify it• e.g., what are integers without addition and substraction?
• Attach functions that work over data types to the data types• Methods/member functions: functions that are attached to
a class3
C++ Classes• Syntax for defining a C++ class
4
class ClassName{
member_type1 member_variable1; member_type2 member_variable2; member_type3 member_variable3;
member_function_prototype(param1, param2,…) member_function_prototype(param1, param2,…) ...
};
C++ Classes• Syntax for defining a C++ class
5
class ClassName{
member_type1 member_variable1; member_type2 member_variable2; member_type3 member_variable3;
member_function_prototype(param1, param2,…) member_function_prototype(param1, param2,…) ...
};
C++ Classes• Syntax for defining a C++ class
6
class ClassName{
member_type1 member_variable1; member_type2 member_variable2; member_type3 member_variable3;
member_function_prototype(param1, param2,…) member_function_prototype(param1, param2,…) ...
};
C++ Classes• Syntax for defining a C++ class
7
class ClassName{
member_type1 member_variable1; member_type2 member_variable2; member_type3 member_variable3;
member_function_prototype(param1, param2,…) member_function_prototype(param1, param2,…) ...
};
Example: Song Class
8
class Song{ char* name_; char* artist_; int duration_s_;
void changeName(const char* new_name); void changeArtist(const char* new_artist); void changeDuration(int duration_s); int compare(const Song& other_song);};
Style Point: Member variables should end in ‘_’
Example: Song Class
9
class Song{ char* name_; char* artist_; int duration_s_;
void changeName(const char* new_name); void changeArtist(const char* new_artist); void changeDuration(int duration_s); int compare(const Song& other_song);};
Best Practice:Don’t define functions in class definition
C++ Classes• Member functions• must be declared in the class definition (prototype)• can be defined elsewhere (more on this later)• have access to all of the member variables
• const member functions• cannot modify member variables• if the method doesn’t modify the member variables,
make it constant• increases flexibility of function• can be called on const objects
10
C++ Classes• Defining class• class in defined between class class_name and };• methods are declared (prototyped) in class definition• class defined in header file • class_name.h
• Defining member methods• methods are often defined in another file• i.e., method bodies written in another file• called cpp file: class_name.cpp
• Why?• splits what a class is and what it does, e.g., Song• from how it actually does it• should only need to read header to figure out how it works
11
Example: Song Class
12
#include “Song.h”
void Song::changeName(const char* new_name){ delete name_; int size = strlen(new_name) + 1; name_ = new char[size]; strncpy(name_, new_name, size);}
...
Must include the header
Example: Song Class
13
#include “Song.h”
void Song::changeName(const char* new_name){ delete name_; int size = strlen(new_name) + 1; name_ = new char[size]; strncpy(name_, new_name, size);}
...
Must state change name is a member function of Song
Example: Song Class
14
#include “Song.h”
void Song::changeName(const char* new_name){ delete name_; int size = strlen(new_name) + 1; name_ = new char[size]; strncpy(name_, new_name, size);}
...can access member data
C++ Classes• Type• description of data it stores• size• allowable operators• can be primitives (built-ins) or classes• e.g., float, int, Song• defining a type does not allocate memory for it
• Instance• an object of a specific type• memory allocated to store that type• can be many instances of a class
15
C++ Classes• Getting an instance of a class• Syntax: class_name variable_name;• Song song1;
• Can access member variables using ‘.’• Syntax: instance.mvariable• cout << song1.artist_ << endl;
• Each instance of a class has its own copy of the member variablesSong song1;Song song2;song1.duration_s_ = 124;song2.duration_s_ = 145;
16
C++ Classes• Each instance of a class has its own copy of the
member variablesSong song1;Song song2;song1.duration_s_ = 124;song2.duration_s_ = 145;
17
song1
name
artist
duration_s 124
song2
name
artist
duration_s 145
C++ Classes• Can call methods on instances of class using ‘.’ tooSong song1;song1.changeName(“Jump Around”);song1.duration_s_ = 124;
18
“Jump Around”
song1
name
artist
duration_s 124
• Let’s write a Integer Matrix class called IntMatrix
19
CODE-A-LONG
Questions?
20
C++ Class Scoping• Scope• the portion of code that a variable can be referenced in
• Nested scopes • scope within a scope• in C++ a new scope starts with { and ends with }
(called a block)• Figuring out which variable a name refers to• called name resolution or lookup
• C++ name resolution (without classes)• it is illegal to reference a variable outside of its scope• first look for the name in block where it was used• then, check enclosing scopes 21
C++ Class Scoping
22
void func1(int a, int b){ int c; c += a;}
void func2(int e, int f){ c += e; // ERROR, c is not in scope}
C++ Class Scoping
23
file scope
nested in
nested in
nested in
disjoint
1 int g;2 void func(int a, int b){3 int d = 7;4 if( a < b){5 int g = 15;6 d += g;7 }8 if( b == d ){9 int c = 210 g = d + c;11 }12}
C++ Class Scoping
24
1 int g;2 void func(int a, int b){3 int d = 7;4 if( a < b){5 int g = 15;6 d += g;7 }8 if( b == d ){9 int c = 210 g = d + c;11 }12}
g = d + c;g -> g from 1d -> d from 3c -> c from 9
d += g;g -> g from 5d -> d from 3
C++ Class Scoping• Classes have their own scope• Member functions are in their class’s scope• they can reference member variables
• C++ name resolution in a class scope1. declarations in the member function body
(including parameters)2. declarations of member data3. declarations in the scope of that encloses the block
(either method definition block or class block)
25
C++ Class Scoping• What if we have a parameter with the same name as a
member variable?• parameter overload the name• name will always resolve to parameter
26
// does nothingvoid Song::changeDuration(int duration_s_){ duration_s_ = duration_s_;}
C++ Class Scoping• The this variable is a pointer to the instance a method was
called on• Give direct access to the instance• Gives access to class scope
27
// sets durationvoid Song::changeDuration(int duration_s_){ this->duration_s_ = durations_s_;}
C++ Class Scoping• Accessing member data outside the class scope• if you have an instance of the class• use the . operator for instances of the class• e.g., cout << song1.name_ << endl;
• use the -> operator for pointers to instances of the class• e.g.,Song* pSong = new Song();cout << pSong->name_ << endl;
28
C++ Class Scoping• Accessing class scope outside the header file• use the :: operator (don’t use with an instance)• we use this to define member functions• e.g., void Song::changeName(const char* new_name){...}
• states that changeName is in the class Song’s scope
29
C++ Class Scoping• Overloading member functions• several member functions can have the same name• as long as they have either different number or different type of
parameters
30
void IntMatrix::init(int rows, int columns){ ...}
void IntMatrix::init(int rowsAndColumns){ // assumes matrix is square ...}
C++ Class Scoping• Overloading member functions• can have the same function in const and non-const varieties
31
// caller can change artistchar* Song::getArtist(){ return artist_;}
// returns an immutable artistconst char* Song::getArtist() const{ return artist_;}
Questions?
32
Constructors• Recall we wrote an init method for TicTacToe• allocated and initialized matrix
• We should use Constructors instead• special kind of initialized function• called when an object is created• should set member variables to their initial values
• Syntax: ClassName(type1 name1, type2 name2, …)• does not specify a return type• can take from 0 to N parameters
33
Example: Song Class
34
class Song{ char* name_; char* artist_; int duration_s_;
Song(const char* name, const char* artist, int duration);
void changeName(const char* new_name); void changeArtist(const char* new_artist); void changeDuration(int duration_s); int compare(const Song& other_song);};
Example: Song Class
35
Song::Song( const char* name,const char* artist, int duration){
// initialize the name this->name_ = new char[strlen(name)+1]; strcpy(name_, name);
// initialize the artist this->artist_ = new char[strlen(artist)+1]; strcpy(artist_, artist);
// initialize the duration this->duration_s_ = duration;}
Constructors• A single class may have many constructors• overload just like any other method• must have different number of parameters or parameter types
36
class IntMatrix{ int **matrix_; int rows_; int columns_;
IntMatrix(int rows, int columns); // makes a square matrix IntMatrix(int rows_and_columns);};
Example: Song Class
37
IntMatrix::IntMatrix(int rows, int columns){ // copy the rows and columns this->rows_ = rows; this->columns_ = columns;
// allocate and initialize the matrix this->matrix_ = new int*[rows_]; for(size_t i = 0; i < rows_; i++){ this->matrix[i] = new int[columns_];
for(size_t j = 0; j < columns_; j++){ matrix[i][j] = 0; }
}}
Example: Song Class
38
IntMatrix::IntMatrix(int rows_and_columns){ // copy the rows and columns this->rows_ = rows_and_columns; this->columns_ = rows_and_columns;
// allocate and initialize the matrix this->matrix_ = new int*[rows_]; for(size_t i = 0; i < rows_; i++){ this->matrix[i] = new int[columns_];
for(size_t j = 0; j < columns_; j++){ matrix[i][j] = 0; }
}}
Constructors• How to use a constructor• use it when creating an instance of a class• syntax: Type varname(arg1, arg2, …)• e.g., Song aSong(“O.P.P.”, “Naughty By Nature”, 271)
• What if we don’t know the duration?• can provide default values for constructor parameters
39
Example: Song Class
40
class Song{ char* name_; char* artist_; int duration_s_;
Song(const char* name, const char* artist, int duration = 0);
void changeName(const char* new_name); void changeArtist(const char* new_artist); void changeDuration(int duration_s); int compare(const Song& other_song);};
Example: Song Class
41
Song::Song( const char* name,const char* artist, int duration = 0){
// initialize the name this->name_ = new char[strlen(name)+1]; strcpy(name_, name);
// initialize the artist this->artist_ = new char[strlen(artist)+1]; strcpy(artist_, artist);
// initialize the duration this->duration_s_ = duration;}
Constructors• What happens if we don’t call the constructor?• e.g., Song aSong;• it calls the Default Constructor
• Default constructor• takes no parameters• syntax: Type()• e.g., Song()• should initialize the member data with sensible empty values
42
Example: Song Class
43
class Song{ char* name_; char* artist_; int duration_s_;
Song(); Song(const char* name, const char* artist, int duration = 0);
void changeName(const char* new_name); void changeArtist(const char* new_artist); void changeDuration(int duration_s); int compare(const Song& other_song);};
Example: Song Class
44
Song::Song(){ // initialize the name this->name_ = NULL;
// initialize the artist this->artist_ = NULL;
// initialize the duration this->duration_s_ = 0;}
Constructors• What happens if we don’t define the default constructor?• If you define no constructors• the compiler makes a default constructor for you• synthesized default constructor• primitive member data is initialized using same rules for
uninitialized variables• member data that are classes are initialized using their
default constructors
45
Constructors• What happens if we don’t define the default constructor?• If you define other constructors• it is a compiler error• e.g., Song aSong; // ERROR
46
Questions?
47
Constructors• Are our member data items implicitly initialized using their
default constructors?
48
class HitSong{ Song hit_song_; int chart_rank_; int singles_sold_;
HitSong( Song& song, int chart_rank, int singles_sold);
...};
Constructors• Are our member data items implicitly initialized using their
default constructors?• it depends
• Constructors have 2 phases1. initialization phase2. general computation phase
• If member data is not initialized after initialization phase,they are constructed using the default constructor• initialization phase ends at {
49
Example: Hit Song Class
50
HitSong::HitSong( Song& song, int chart_rank, int singles_sold){
// at this point // this->hit_song_ == Song() // this->chart_rank_ == undefined // this->singles_sold_ == undefined
this->hit_song_ = song; // overwrites memory this->chart_rank_ = chart_rank; // overwrites this->singles_sold_ = singles_sold;}
Constructors• How can we initialize member data before the { ?• Use the construction initializer list• Syntax:
Type(T1 parm1, T2 parm2) : member1(parm1), member2(parm2){• initializes the member data just like you had written:
T1 member1(parm1);T2 member2(parm2);
• sometimes called member initialization list
51
Example: Hit Song Class
52
HitSong::HitSong( Song& song, int chart_rank, int singles_sold) : hit_song(song), chart_rank_(chart_rank),singles_sold_(singles_sold) {
// nothing left to do}
Constructors• You must use the construction initializer list if member data
doesn’t provide a default constructor
• Initializers may be an expression• e.g., chart_rank_(chart_rank * 7 + 5)
• Member data initialized in order of definition,NOT in order of construction initialize list
53
Example
54
class TwoInts{ int a_; int b_; TwoInts(int c);};
// ERRORTwoInts::TwoInts(int c) : b_(c), a(b_){}
// OKTwoInts::TwoInts(int c) : a_(c), b_(a_){}
// Also OKTwoInts::TwoInts(int c) : a_(c), b_(c){}
Constructors• Why you should always define a default constructor?• If you don’t define a default constructor for class A:1. Every constructor of every class that stores an A must
explicitly initialize it in construction initializer list
2. The compiler won’t synthesize default constructors for classes with A as member data
3. Cannot dynamically allocate an array of As
4. Statically allocated arrays of As must be explicitly initialized
5. Other sometimes unexpected problems
55
Protecting Member Data• Member data shouldn’t be visible to everybody• what if some user of our class screws up our member data
• What if we need methods to do internal work?• stuff that users of our class shouldn’t be able to call
• Need a way to protect member data and some methods
56
Protecting Member Data• Use access labels• change visibility of methods and member data• public: accessible by all parts of the program• private: accessible only inside the class scope• label in effect until another label encountered• default label is private
57
Example: Song Class
58
class Song{
private: char* name_; char* artist_; int duration_s_;
public: Song(char* name, char* artist, int duration = 0);
void changeName(const char* new_name); void changeArtist(const char* new_artist); void changeDuration(int duration_s); int compare(const Song& other_song);};
Questions?
59
Static Members• What if you have an object that every instance of a class needs
to share?• e.g., count of how many instances were created• e.g., shared set of error messages
• Could make it a global variable• then anyone can modify it
• Can we make an object that is shared by all instances of a class, but is not visible outside this class?
60
Static Members• Class static member data and methods• Advantages over global variables
1. Reduces namespace pollution• name of static member is in scope of the class
2. Limits visibility• static member data can be private
3. Clear association• variable clearly associated with enclosing class
61
Static Members• Declaration syntax • static type varname• e.g., static int default_value_;
• Usage syntax• outside of declaring class: Class::varname• e.g., IntMatrix::default_value_• inside declaring class: varname• e.g., default_value_
62
Static Members
63
class IntMatrix{ private: int **matrix_; int rows_; int columns_; public: static int default_value_;
IntMatrix(int rows, int columns); ...};
Static Members
64
IntMatrix::IntMatrix(int rows, int columns){ // copy the rows and columns this->rows_ = rows; this->columns_ = columns;
// allocate and initialize the matrix this->matrix_ = new int*[rows_]; for(size_t i = 0; i < rows_; i++){ this->matrix[i] = new int[columns_];
for(size_t j = 0; j < columns_; j++){ matrix[i][j] = default_value_; }
}}
Static Members
65
void main(){ IntMatrix i_matrix; int top_left = i_matrix.getCell(0,0) if( top_left == IntMatrix::default_value_ ){ cout << “Top left value unitialized”; }}
Static Members• Definition• static data members must be defined exactly once outside of the
class body• Cannot be initialized in constructor• constructor called many times• static member data should be initialized once
• Ordinary convention is to tack initialization on at end of source file (.cpp)
• Syntax• type Class::varname = init_value;
66
Static Members
67
IntMatrix::IntMatrix(int rows, int columns){ ...}
int IntMatrix::default_value_ = 0;
director’s cut
Static Members• Static member data’s special features
• Constant static integrals can be initialized in the class body
68
class IntMatrix{ private: int **matrix_; int rows_; int columns_; const static int default_value_ = 0;
public: IntMatrix(int rows, int columns); ...};
Static Members• Static member data’s special features
• Static member data is not a part of any class instance, so:• a static data member can be the same class type of its
enclosing class
69
class IntMatrix{ private: int **matrix_; int rows_; int columns_; static IntMatrix nested_matrix_; ...};
Static Members• Static member data’s special features
• Static member data is not a part of any class instance, so:• a static data member can be used as a default argument
70
class IntMatrix{ private: int **matrix_; int rows_; int columns_; const static int DEF_ROWS_ = 3; public: IntMatrix(int rows = DEF_ROWS_, int columns);
};
Static Methods• Classes can also have static methods
• These methods have no this pointer
• Declaration syntax• static return_type method(t1 parm1, t2 parm2)• e.g., static int minuteToMillis(float minutes)
• Definition syntax• return_type Class::method(t1 parm1, t2 parm2)• e.g., int Time::minutesToMillis(float minutes)
71
Static Methods• Useful for reasons similar to static member data1. Reduces namespace pollution• name of static method is in scope of the class
2. Limits visibility• static method can be private
3. Clear association• method clearly associated with enclosing class
4. Can be used to initialize static member data• for non-integral complex member data
72
Static Methods• Can initialize static member data with static method
73
class CircleMath{ private: const static float pi; static float initPi(); ...
};
Static Methods• Can initialize static member data with static method
74
float CircleMath::initPi(){ return 3.14159f;}
float CircleMath::pi = initPi();
director’s cut
Classes Discussion• Data abstraction• separate what something does from how it does it• interface: what it does• implementation: how it does it• allows code to be broke into modules• coding can be gluing modules together instead of rewriting same
code again and again
• Class abstraction• interface is public methods and public member data• implementation includes method definitions, private methods,
and member data75
Classes Discussion• Encapsulation• don’t just separate interface from implementation• hide implementation• enforces good data abstraction
• Class encapsulation• anything declared private• classes also glue together related data so it can be
modified together
76
Questions?
77