Structuring Your Data Using Classes Chapter 8. What We’ll Cover in Chapter 8 Classes and how they...

Post on 11-Jan-2016

213 views 1 download

Transcript of Structuring Your Data Using Classes Chapter 8. What We’ll Cover in Chapter 8 Classes and how they...

Structuring Your DataUsing Classes

Chapter 8

What We’ll Cover in Chapter 8

• Classes and how they are used• The basic components of a class• How a class is declared• Creating and using objects of a class• Controlling access to members of a class• Constructors and how to create them• The default constructor• References in the context of classes• The copy constructor and how it is

implemented

Data Types, ObjectsClasses and Instances

• Basic variables don’t describe objects

• Can’t describe a box in terms of int

• Can make a struct of type Box– Length– Breadth– Height

• Can create, manipulate, destroy as many boxes as you wish

Data Types, ObjectsClasses and Instances

• Structs in C different from structs in C++

• Structs in C++ almost identical to classes– Except for control to access to its members– More on that later

• See class definition of a box on p. 280

• Data members– m_Length, m_Breadth, m_Height– m_ indicates it’s a data member

Data Types, ObjectsClasses and Instances

• Called the class CBox– The C indicates that it is a class

• Always stick to naming conventions– Helps you in debugging– Helps those who come after you, too

• public keyword– Clue to difference between structures and

classes

Keyword public

• Allows access to these members from outside the class– Just like members of a struct– Members of structs public by default

• In classes, can restrict access to members

• Can declare an instance of class CBox– An instance is one specific item of the class

• CBox bigBox;

First Class

• Objects and instances are same thing

• Notion of class invented by an Englishman– Thought people would be happy knowing their

place and staying within it

• C++ invented by Bjarne Stroustrup– Danish– Learned class concepts while at Cambridge

University in England– Appropriated the idea successfully for C++

First Class

• Very similar to English class system

• Classes have– precise role– permitted set of actions

• Different from English system– Somewhat socialist– Focuses on working classes– Working classes live on backs of classes that

do nothing

Operations on Classes

• Can create data types to describe whatever you want

• Can also define operations that act between your objects– See p. 281

• Very powerful concept• Not programming in terms of computers• Programming in terms of problem-related

objects

Terminology• Class

– User-defined data type

• Object-oriented programming– Programming style based on defining your

own data types

• Instantiation– Creating an instance of a class

• Object– An instance of a particular class type

• Encapsulation– Packaging data with the related functions

Understanding Classes

• A class– Contains data members to define the object– Contains functions that operate on data

• Data elements– Single data elements– Arrays– Pointers– Arrays of pointers (of any kind)– Objects of other classes

Defining a Class

• Defined very similarly to a struct

• Exception: public

• All values relative to object are defined as members of the class

• All member names local to the class

• Can use same names elsewhere

Access Control In a Class

• Keyword public– Class members accessible anywhere within

scope of class object

• Keyword private– Class members accessible only within the

class itself– More on this later

• Difference between struct and class– Struct is public by default; class, private

Declaring Objects of a Class

• Declaration of objects just like other declarations– CBox box1;– CBox box2;

• Two instances of type CBox– Can have different values– Two different boxes have two different sizes– Two different volumes

Declaring Objects of a Class

• See chart p. 284

• Data members of each object– Not initialized to anything– Will need to access them to do so– Othewise will contain junk values

Accessing Data Membersof a Class

• Accessed same way as members of a struct– Using direct member selection operator– box2.m_Height = 18.0;– Sets value of height of box 2 to 18.0 (inches)

• Let’s look at an example on p. 284

EX8_01.CPP

• Do the includes

• Declare class CBox– 3 members– Length– Height– Breadth

• Then we go into main( )

EX8_01.CPP

• Declare two instances of type CBox

• Declare and initialize variable boxVolume– Type double– Initial value 0.0

• Set values for first box

• Set values for second box– Can use formulas and values from first box

EX8_01.CPP

• Calculate boxVolume for first box– Using standard math for volume

• Output the volume for box 1

• Calculate sides sum for second box– Using standard math there, too

• Output the size of variable type CBox– Using sizeof operator– Just like other data types

EX8_01.CPP

• Can see the output of this program

• Page 286

• Notice that the data members are of type public– Can be accessed from outside the class– Class was declared globally so members

accessible from anywhere in the program

Member Functions of a Class

• Member functions in a class can access members declared as private

• In the words of Ted Koppel,– “Let’s take a look.”

EX8_02.CPP

• Same as example 01

• We add a member function

• Includes done

• Declare class box with its members

• Declare member functionf– double Volume( );– Returns value calculated by standard math– Same as in main( ) in example 01

EX8_02.CPP

• In main( ), everything similar to before

• boxVolume = box1.Volume( );– Assigns to boxVolume the value returned by

member function Volume in instance box1

• Output statement calls box2.Volume( )– Will get completely different value from that

assigned to boxVolume– Two different boxes; two different volumes

EX8_02.CPP

• Names of class members automatically refer to current object

• When box1.Volume( ) is run– Members m_Length, m_Height, m_Breadth all

refer to those values for box1

• Output from example 02 is on p. 288• Note that size of CBox doesn’t change

with added function• Functions don’t change size of a class

Positioning a MemberFunction Definition

• Can place function declaration outside the class

• Must include function prototype within the class

• When function definition is coded, must tell compiler what class function is for

• Use the double colon ( :: ) to do this

• double CBox::Volume( )

Inline Functions

• Compiler expands these in the code– In place of the call to the function– Compiler ensures that problems of variable

names and scope are avoided

• Can define function as inline– inline double CBox::Volume( )

• Avoids overhead of calling the function– Passing variables, etc.

Inline Functions

• Can use the inline definition for regular functions as well

• Just remember it’s best for short, simple functions

Class Constructors

• In EX8_02.CPP, manually initialized all members of box1 and box2

• Unsatisfactory because– Easy to overlook a data member– Lots of code needed for complex classes

• Especially if several instances need initialization

– Can’t access private members of the class• Must be initialized from within the class

• Solution: Class Constructors!

What is a Constructor?

• A special function in a class

• Called when a new object of the class is declared

• Initializes objects as they are created

• Ensures that data members hold valid values

• Constructor name same as class name– CBox( ) is constructor for class CBox

What is a Constructor?

• Constructor has no return type– Not even void

• Must not write a return type

• Assigns initial values only

• No return type necessary or permitted

EX8_03.CPP

• Class definition changed to include function CBox( )

• Function CBox( ) takes three parameters– One for each data member– Assigns three parameters to data members

• In main( ), instantiation includes initial values, in sequence

• box1 and cigarBox both initialized

EX8_03.CPP

• Output calls cigarBox.Volume( )

• Works because cigarBox is of type CBox– Returns value calculated from initial values

• Output shows box1 volume same as before

• cigarBox volume also works

The Default Constructor

• If we declare instance of CBox without giving initial values– CBox box2;

• Error message will result

• Need default constructor in case initial values not given

• Worked before because we had not supplied a constructor

The Default Constructor

• When constructor provided, all declarations should match its input requirements

• Unless we supply default constructor– Should always supply default constructor

• In simplest terms, default constructor has no parameters, no content

• It’s just there

Default Constructor

• Let’s include a default constructor to our program

EX8_04.CPP

• Inside the class, data members declared

• Constructor function is there

• Default constructor then provided

• It doesn’t do anything but say it was called

• But it allows for declarations without values

• In main( ), box2 declared without values

• Then box2 defined relative to box1

EX8_04.CPP

• At that point, box2.Volume( ) will work

• Output on p. 294 shows where constructor is called

• Then default constructor called– Box2 declared without initial values

• All volume calls return valid information

• Rest of program still working fine

• Can overload constructors just like functions

Assigning Default Valuesin a Constructor

• Makes a little more sense than an empty function

• Can declare default values same as with functions– In function header– In function prototype if function not within

class

• The changes listed at bottom of p. 294– Will result in error messages

Assigning Default Valuesin a Constructor

• Why? Because either constructor can now be called for declaration of box2

• Compiler won’t know which one to use

• Solution: delete the default constructor

• Means that instances without values are automatically assigned default values

• Preferable to uninitialized data members

EX8_05.CPP

• Includes are normal

• Define class CBox– Data members– Constructor defined with default values– Values assigned to data members– Function Volume( ) included

EX8_05.CPP

• In main( )– Instantiate box2 of type CBox– Output statement uses call to box2.Volume( )– End program

• Output demonstrates that values are initialized using the default values– m_Height, m_Length, m_Breadth all = 1

A Side Trip – Stacks

• Just like like the stack of plates at Ryan’s• Last one on is first one off• Can be used for data management

– When most recent data is needed

• Often used in memory management in programming

• Functions that call other functions are placed on the stack while new function runs

A Side Trip – Stacks

• New function runs, then exits– (disappears)

• Pull calling function from the stack– Continues execution

• Works when function calls another function which then calls another function

Hands-On Project

• Using EX8_05.CPP as a starting point

• Replace the class for a box with a class for a cylinder

• Have two values (radius & length)

• Make the necessary changes to the function Volume– Make it return the volume of the cylinder

π r2 * length = volume

Using an Initialization ListIn a Constructor

• Alternative to initializing members individually in a class constructor

• Initialization list• See p. 296• Initialization list goes after the function

header– Separated by a colon ( : )

• Replaces individual assignment statements

Using an Initialization ListIn a Constructor

• This technique very important

• Some data members of a class can only be initialized this way.– We will see this later on

Private Members of a Class

• Need to protect data members

• Should only be modified from specific places

• Data members should only be accessible (for change) by member functions

• Normal functions (not member functions) cannot have access to private members

• See diagram p. 297

Private Members of a Class

• Separation of the implementation of a class from its interface

• Can have public member functions which can return values from private members

• Allows outside access to the values but not access to changing them

• Can modify implementation without changing the interface to rest of program

EX8_06.CPP

• Includes, blah, blah, blah

• Class CBox is declared

• Constructor is called as public– Has to be– Called at instantiation

• Function Volume is public– Called from outside the class– Doesn’t change data values

EX8_06.CPP

• Data members now listed as private

• Cannot be assigned values outside class

• Cannot be viewed from outside the class

• In main, declare two instances of CBox– One with initial values, one without

• Call match.Volume( )– Is okay: Volume is a public function in CBox

• Two commented lines

EX8_06.CPP

• Second commented line attempts to modify data member of box2

• Can call Volume of box2– Volume is still public

• End program

• See example of output middle of p. 299

• Members are private by default

• Still better to explicitly state it

Accessing private Class Members

• If members are private, how do we get the information?– Without being able to use info, it’s useless

• Make a public function which returns the value in a private member

• Allows use of the value but not modification

• See example on p. 300

Accessing private Class Members

• Written as member function external to the class

• Declared as inline because it’s small and simple

• Can use GetLength( ) in an assignment statementlen = box2.GetLength( );

Friend Functions of a Class

• Not a member of the class

• Access attributes do not apply to them

• Just ordinary global functions– With special privileges

• Can access all members of a class

• Keyword friend

Friend Functions of a Class

• Can include the prototype of a friend function in the class– Or

• Can include the whole function definition– Friend functions defined within the class

definition are inline by default.

• Let’s examine an example…

EX8_07.CPP

• Includes taken care of

• Define class CBox

• Constructor defined (public)

• Function Volume( ) defined (public)

• 3 data members defined (private)

• Friend function defined– Prototype included in class definition

• Class definition ends

EX8_07.CPP

• Friend function defined globally

• Receives instance of CBox as parameter

• Returns value for surface area of sides

• Friend function ends

• In main( ) instantiate two boxes– One with initial values; one without

• Output volume of CBox called match

EX8_07.CPP

• Output surface area of match– Call friend function BoxSurface– Send match as argument

• Output volume of box2

• Output surface area of box2– Call friend function BoxSurface– Send box2 as argument

• End program

EX8_07.CPP

• Note that in function BoxSurface– Data members accessed using instance and

member name

• BoxSurface not a member of class CBox– Not affected by public and private attributes

Placing friend Function DefinitionsInside the Class

• Can be done

• Problems, though, with readability

• friend function still global but doesn’t look it

• Function would not show up in ClassView

• Best not to do this

The Default Copy Constructor

• box1 declared and initialized (p. 302)

• Can initialize a second instance of CBox (box2) with box1

• The default copy constructor– Generated by the compiler

• Initializes second instance of CBox– Using first instance (box1)

• Can do this only with simple classes

The Default Copy Constructor

• Cannot use this for extensive classes– Which include pointers or arrays as members– Can cause serious errors in your program

• We need to create our own copy constructor– Coming soon to a chapter near you!

The Pointer this

• When member function called, it contains hidden pointer called this

• Points to object specified when member function calledBoxVolume = box1.Volume( );

• Results in pointer this pointing to box1

• Accessing member m_Length actually results in this->m_Length

The Pointer this

• this->m_Length

• Fully-specified reference to object member being used

• Can use pointer this explicitly as well

• Might need to return pointer to current object

• Let’s take a look.

EX8_09.CPP

• Everything same as EX8_08.CPP until we get to the new function Compare– To compare two boxes

• In main, CBoxes match and cigar instantiated

• If statement calls function Compare in the class

Compare( ) function

• Could have been written as a separate function

• See bottom of p. 306• Function returns type int• Two parameters – the two boxes, of

course• The return function is similar in structure to

the example• Call to function (p. 307) looks neater, too• There is actually a better way (Ch. 9)

const Objects of a Class

• Sometimes const object of a class is needed– A box of a standard size, for example

const CBox standard(3.0, 5.0, 8.0);– Once set, we don’t want to change it

• The functions inside a class don’t change the objects, just return values from them

const Objects of a Class

• If an object is declared as const, no member function (that might alter it) can be called for it

• Try changing cigar in EX8_09.CPP to type const

• Will get an error• Produced because of the Compare( )

function• Function uses this without making it const

const Objects of a Class

• Objects declared as const have a this pointer that is also const

• Compiler will not allow call to any member function that does not assume this to be const

• Need to find out how to make this a const

const Member Functionsof a Class

• Must declare the function const in the class

• See p. 308

• Function Compare( ) declared a const by appending the word to end of header– Does not work for ordinary global functions

• Now the this for Compare( ) will be const

• const functions cannot call non-const ones within a function; might modify something

const Member Functionsof a Class

• When you declare an object as const, member functions called for it must also be const.

Member Function DefinitionsOutside The Class

• Both the function header and function prototype must have const appended

• Should declare all member functions that do not modify data members as const

• Example at the top of 309 shows this in practice

• All member functions defined outside the class (separately)

Member Function DefinitionsOutside the Class

• const modifier appended to each function prototype in the class

• const modifier appended to each function header as well

• If prototype declared as const, function must also be declared as such– Otherwise, won’t compile

• Function with const and function without are two different functions

Arrays of Objects of a Class

• Declared just like arrays of built-in types

• Each element of array of objects causes default constructor to be called

• Let’s see an array of objects in use– Why do I feel like it’s gonna be boxes?

EX8_10.CPP

• Includes done• Class CBox defined• Constructor defined with only 2 default values

– Makes compiler automatically use other default constructor we have provided

• Specific default constructor defined as well– Sets all three side measurements to 1.0

• Function Volume( ) defined as before• Data members defined as private

EX8_10.CPP

• Declare array of CBox objects– Five elements

• Declare instance cigar box of CBox

• Output statement– Volume of fourth “box” (element 3 in array)– Volume of cigar box

• End program

• Output is on page 311

EX8_10.CPP

• Notice that default constructor is called five times– Once for each element in the array boxes

• Then constructor is called once– For cigar box (for which figures were

provided)

Static Members of a Class

• Data members and function members of a class– Can be declared as static– More to it than effects of keyword static

outside a class context

Static Data Members of a Class

• Static data members defined only once

• Shared among all instances of the class– Regardless of how many are declared

• Each instance gets own copies of ordinary data members

• Only one instance of a static data member exists

• See diagram p. 311

Static Data Members of a Class

• One use for static data members– Count how many objects of the class exist

• Could add static data member objectCount to definition of CBox as follows

Static int objectCount;

Static Data Members of a Class

• Initialization is a problem

• Can’t do it in the class definition– That’s just a blueprint, not an actual object

• Can’t do it in a constructor– Want to increment it each time an object is

created

• Can’t initialize it in a member function– Need it initialized prior to any object’s creation

Static Data Members of a Class

• We write the initialization outside the class definition

Int CBox::ObjectCount = 0;

• Keyword static not included

• Must use the class name and scope resolution operator ( :: )

• Compiler needs to know this is static member of CBox class

EX8_11.CPP

• Counting Instances

• Includes

• In the definition of the class

static int objectCount;

• In the constructor, objectCount increments

• Means it increments for each instance created

• Increment statement in both constructors– Because only one or the other will be called

EX8_11.CPP

• After definition of CBox

• Static data member is initialized– With qualifying class name & SRO

• In main, array of 5 boxes is declared

• One cigar box declared, with initial values

• Output statement gives us number of boxes created (through the class)

EX8_11.CPP

• Second output statement gives us number of boxes created (through one instance)

• End the program

• Output on p. 313

• Demonstrates that how we refer to static data member is irrelevant– Through class– Through instance of the class– Value is the same

EX8_11.CPP

• The count of 6 includes the five boxes in the array and the cigar box

• Static members of a class exist even prior to any instantiation of that class

• It must have; we initialized it before main( )

• Static data members– Automatically created at start of program– Automatically initialized to 0

EX8_11.CPP

• Static data members only need to be initialized if– Initial value is other than 0– Still need to know how to initialize in the event

you need to initialize another value

Static Function Members of a Class

• Static function member is independent of any particular instance of the class

• Must use qualified names to reference members of a class– Just as you would from a global function

• Static member function can be called even if no instance of the class yet exists

Static Function Members of a Class

• Can only access static data members if no instance exists– They’re the only data members that exist prior

to instantiation

• Can use static function to access static data, even when you are unsure if an instance exists

• Could be used to see if an instance exists• If static data member = 0, none exists

Static Function Members of a Class

• If static data member != 0– Can determine how many instances of the

class exist– (using previous example)

• Once objects have been defined– Static function can access private and public

data members

• Static function prototypeStatic void Afunction(int n);

Static Function Members of a Class

• Can call that function relative to specific object as such:

aBox.Afunction(10);• Where aBox is an object of the class• Can call that function without reference to

an objectCBox::Afunction(10);

• This lets the compiler know what class the function Afunction( ) belongs to

Pointers and Referencesto Class Objects

• Very important to object-oriented programming

• Considerable amounts of data in class objects

• Pass-by-value very time consuming and inefficient

• Some techniques involving references are essential to some class operations

Pointers to Class Objects

• Declared same as other pointers• Pointer to objects of class CBox is:

CBox* pBox = 0;• (Remember: initialize pointer to 0!)• Can now assign pointer to CBox object

pBox = &cigar;• Can access members same as with the this operator: cout << pBox->Volume( );

EX8_12.CPP

• Exercising the indirect member access operator ( -> )

• Includes done

• Constructors defined in the class

• Function Volume( ) is defined

• Function Compare( )– Now takes a pointer to a CBox object– Uses pointers this and pBox

EX8_12.CPP

• Data members declared as private

• In main( ) array of five boxes declared

• CBoxes cigar and match declared

• Pointer pB1 to cigar defined

• Pointer pB2 defined, initialized to 0

• Output statement uses pointer pB1 twice– Once for address of cigar– Once to access Volume( ) for cigar

Ex8_12.CPP

• Assign address of match to pointer pB2

• Use Compare( ) from pB2

• Send pB1 as argument

• Compare works as always– Notice that the names of the individual boxes match and cigar are hard-coded

– Wouldn’t normally do this when using pointers– Would want to be able to assign any box

EX8_12.CPP

• The call to Compare( ) in the if statement results in either 1 or 0 being returned

• We then reassign address of array boxes to pB1

• Assign box match to third element of the array

• Output statement calls Volume( ) using pointer pB1 and pointer arithmetic

• Then end the program

References to Class Objects

• References’ full value understood when used with classes

• References to class objects declared exactly as they are with other data types

• CBox& rcigar = cigar;– Defines reference rcigar to box cigar

• Can output volume of cigar using reference: cout << rcigar.Volume( );

References to Class Objects

• Remember that references act as aliases to the variables they refer to

• Works just like other references

Implementing a Copy Constructor

• Copy Constructor– Initializes an instance of a class using another

instance (existing)– Has to accept object of the class as an

argument

CBox(CBox initB);– Constructor called: CBox myBox = cigar;– Generates call to constructor as follows:

CBox::CBox(cigar);

Implementing a Copy Constructor

• Can’t do that. Pass-by-value makes a copy of the argument

• Would result in an infinite number of calls to the copy constructor

• Solution: use a const reference parameter

CBox(const CBox& initB);

• No copying when references passed as parameters

Implementing a Copy Constructor

• Function accesses the argument variable in the caller function directly

• Use of const ensures that function can’t modify the argument– Wouldn’t want to do that in a copy constructor– Just want to copy the values out of it

• Let’s see how to implement the copy constructor using this knowledge

Implementing a Copy Constructor

CBox::Cbox(const CBox& initB){

m_Length = initB.m_Length;m_Breadth = initB.m_Breadth;m_Height = initB.m_Height;

}• Qualifier ( CBox:: ) assumes this

constructor is outside the class definition

Implementing a Class Constructor

• Uses the scope resolution operator ::

• Uses values of object passed as an argument to initialize values in object being instantiated

• Could have used initialization list to set initial values

• More about why and when to write copy constructors in Chapter 9