c++ data types. structs vs. classes c++ classes

36
C++ data types Fundam ental (orsim ple orscalar): A data object of one of these types is a single object. - int , double , char , bool , complex , and the related types( unsigned , short , etc.) - enum erations Structured: C ollections of data - arrays, structs, unions, classes, valarrays, bitsets the containersand adaptersin STL

Post on 20-Dec-2015

235 views

Category:

Documents


0 download

TRANSCRIPT

C++ data types

• Fundamental (or simple or scalar):A data object of one of these types is a single object.- int, double, char, bool, complex,

and the related types (unsigned, short, etc.)- enumerations

• Structured: Collections of data- arrays, structs, unions, classes, valarrays, bitsets

the containers and adapters in STL

Structs vs. Classes

Similarities

1. same syntax

2. Both used to model objects with

different attributes (characteristics) represented asdata members (also called fields or instance variables).

Thus, both used to process non-homogeneous datasets.

Structs vs. Classes

Differences

1. C does not provide classes;C++ provides both structs and classes.

2. Members of a struct by default are publiccan be accessed outside the struct

by using the dot operator

Members of a class by default are privatecannot be accessed outside the struct

but can be explicitly declared public

C++ ClassesC++'s structs and classes model objects that have:• Attributes (characteristics)

represented as data members• Operations (behaviors)

represented as function members (methods).

classes new style of programming : Object-Oriented

Objects are self-contained,Associated with their own operations

the I can do it myself principlerather than being passed as a parameter to an external

function that operates on them and sends them back.

Common Forms of Declaring a Class

class ClassName{// private by default

Declarations of private memberspublic:Declarations of public members

};

class ClassName{public: //"interface" of class given 1stDeclarations of public members

private:Declarations of private members

};

Notes on Declaring a Class

1. Data members are normally placed in the private section of a class; Function members in the public section.

2. Some programmers prefer to put the private section firstUse the default access for classesOmit the private: specifier

3. Other programmers put the public interface of the class firstand the hidden private details last.

(In the book, we use the latter approach)

4. Although not commonly done (poor technique), a class may have several private and public sections;

the keywords private: and public: mark the beginning of each.

Access to Class Members

A particular instance of a class is called an object :

ClassName object_name;

Private members can be accessed only within the class(except by friend functions to be described later).

Public members can be accessed within or outside the class.

to access them outside the class, one must use the dot operator:

object_name.public_member_name

Class declarations are placed in a header file whose name is ClassName.h

Header file for class Time — Version 1

/** Time.h ----defines the data type Time with operations Set: To set the time Display: To display the time

*/#include <iostream>using namespace std;

class Time{ /******** Member functions ********/public:

/* sets data members of(Time)object to specified values * Receive: hours, minutes (in standard time) * AMPM ('A' if AM, 'P' if PM)

*/

void Set(unsigned hours, unsigned minutes, char am_pm);

Header file for class Time — Continued

/* Display displays time in standard and military format* using output stream out.** Receive: ostream out* Output: The time represented by Time object* for which this function invoked***************************/// const function: cannot modify data members// good practice: protects data members from// accidental modification.void Display(ostream & out) const;

private: // Data Members unsigned myHours, myMinutes; char myAMorPM; // 'A' or 'P' unsigned myMilTime; // military time equivalent}; // end of class declaration

Data Members: Why private?"Hidden" data members Cannot be accessed outside class application programs must interact with an object through its interface public member functions control interaction between programs and class. Application program need not know about implementation!

Implementation may changeIf interface is constant, programs using an object need not be changed.

What's wrong with tying application code to implementation details?A change in implementation forces a change in the application code

Increased upgrade time. Increased programmer cost Decreased programmer productivity Reduced profits due to

— Delayed releases/upgrades— Loss of customer confidence in software reliability

Implementation of a Class

Class declaration contains Declaration of data members Prototypes (declaration) of member functions

Member functions are not usually placed in class declaration clutters up the interface definitions placed outside class header must tell compiler where the declaration/prototype is

Use the scope operator :: which has the form

ClassName::ItemName(the qualified or full name of ItemName.)

Implementation of class Time — Version 1// Time.cpp -- implements the Time member functions#include "Time.h"

/* ToMilitary converts standard time to military time. Receive: hours, minutes, am_pm Return: The military time equivalent Could implement this utility function as private class method

*/int ToMilitary (unsigned hours, unsigned minutes, char am_pm){ if (hours == 12) hours = 0; return hours * 100 + minutes + (am_pm == 'P' ? 1200 : 0);

}

void Time::Display(ostream & out) const{ out << myHours << ':' << (myMinutes < 10 ? "0" : "") << myMinutes << ' ' << myAMorPM << ".M. (" << myMilTime << " mil. time)";

}

Implementation of class Time — Continued

void Time::Set(unsigned hours, unsigned minutes,char am_pm)

{ // Check class invariant if (hours >= 1 && hours <= 12 && minutes >= 0 && minutes <= 59 && (am_pm == 'A' || am_pm == 'P')) { myHours = hours; myMinutes = minutes; myAMorPM = am_pm; myMilTime = ToMilitary(hours, minutes, am_pm); } else cerr << "*** Can't set time with these values ***\n"; // Object's data members remain unchanged}

Test driver for class Time

#include "Time.h"#include <iostream>using namespace std;

int main(){ Time mealTime; mealTime.Set(5, 30, 'P');

cout << "We'll be eating at "; mealTime.Display(cout); cout << endl;}

ExecutionWe'll be eating at 5:30 P.M. (1730 mil. time)

Object-Oriented Perspective

Procedural: send object off to some function for processingOO: send a message to the object to operate on itself.

To set my digital watch to 5:30 P.M.,I don't wrap it up and mail it off to Casio.I push a button!

To display the time on my watch,I don't wrap it up and mail it off to Casio and have them tell me what

time it is.I have it display the time itself, perhaps pushing a button to turn on the

backlight so I can see it .

Class Constructorsconstructing an object consists of:

allocating memory for the object, and initializing the object.

In our example, after the declaration

Time mealTime;

memory has been allocated for object mealTimebut it's data members are not initialized

(likely to contain "garbage" values).

Need to:

specify initial values for mealTime provide default values to be used if no initial values are specified.

Class Constructors - Properties names are always the same as the class name. initialize the data members of an object

with default values or values provided as arguments do not return a value

- have no return type (not even void). often simple and can be inlined called whenever an object is declared. If no constructor is given in the class, compiler supplies a default

- constructor which allocates memory and- initializes it with some default (possibly garbage) value

A default constructor is one that is used when the declaration of anobject contains no initial values:

ClassName object_name;

Constructors for Time class

// Time.hclass Time{public:

/** Construct a class object (default). * Precondition: A Time object has been declared. * Postcondition: Time object is initialized to 12:00 A.M.;**********************/Time();

/* --- Construct a class object (explicit values). * Precondition: A Time object has been declared. * Receive: Initial values initHours, initMinutes, and * initAMPM * Postcondition: Time object are initialized to passed values **********************/Time(unsigned initHours, unsigned initMinutes, char initAMPM); . . . // other member function prototypes

private: /********** Data Members **********/ . . .}; // end of class declaration

Constructors for Time class - Implementation

inline Time::Time(){ myHours = 12; myMinutes = 0; myAMorPM = 'A'; myMilTime = 0;}

Time::Time(unsigned initHours, unsigned initMinutes, char initAMPM){ // Check class invariant assert(initHours >= 1 && initHours <= 12 && initMinutes >= 0 && initMinutes <= 59 && (initAMPM == 'A' || initAMPM == 'P'));

myHours = initHours; myMinutes = initMinutes; myAMorPM = initAMPM; myMilTime = ToMilitary(initHours, initMinutes, initAMPM);}

Create and initializes 2 Time objects

Time mealTime, //default constructorbedTime(11,30,'P'); //explicit-value constructor

Code:

mealTime.Display(cout);cout << endl;bedTime.Display(cout);cout << endl;

Execution:12:00 A.M. (0 mil. time)11:30 P.M. (2330 mil. time)

Constructors for Time class - Default Parameters

Can combine both constructors into a single constructor function byusing default arguments:

Replace constructors in Time.h with:/* --- Construct a class object. Precondition: A Time object has been declared. Receive: Initial values initHours, initMinutes, and initAMPM (defaults 12, 0, 'A') Postcondition: Time object initialized to initHours, initMinutes, and initAMPM , respectively.---*/

Time(unsigned initHours = 12, unsigned initMinutes = 0, char initAMPM = 'A');

Note: Any parameter with default argument must appear after all parameterswithout default arguments.

Copy Operations

Two default copy operations are provided:1. Copy in initialization (copy constructor)

2. Copy in assignment (assignment operator)

Each makes a (byte-by-byte) copy of the datamembers of the object.

Called a bitwise or memberwise copy.

Examples:Time t = bedTime; // copy constructor calledTime t(bedTime); // copy constructor called

Both:1. Allocate memory for t2. Copy data members of bedTime so t is a copy ofbedTime

In contrast:Time t = Time(11, 30, 'P');

calls the explicit-value constructorto construct a (temporary) Time object and then

copies it (via the assignment operator) into t.

Data members are private: they cannot be accessed outside the class.

To make the values stored in some or all of these members accessible,provide access member functions

Example:provide access to myHours of class Time.

(access for the remaining members is analogous.)

simply retrieves the value stored in a data member inline prototype (and define) as a const function

// add to class Timeinline unsigned Time::Hour() const;{ return myHours; }

Access Member Functions

Output and Input

Add output operation(s) to a class early use for debugging.

Example: overload operator<< for a Time object

cout << "We'll be eating at "<< mealTime << endl;

instead of

cout << "We'll be eating at " ;mealTime.Display(cout);cout << endl;

Overloading operators

In C++,operator can be implemented with the function

operator()

— If a member function of a class C, and a is of type C,the compiler treats a b as

a.operator(b)

— If not a member function of a class C,the compiler treats a b as

operator(a, b)

Overloading Output Operator <<

Can operator<<() be a member function?

No, because the compiler will treatcout << t as cout.operator<<(t)

which means that operator<<() is a member of class ostream!

Putting the prototypeostream& operator<<(ostream& out, const Time& t);inside the class declaration causes a compiler error like:

'Time::operator <<(ostream &, const Time &)'must take exactly one argument

operator<<() as a member function of Time means thatit has the Time object as an (implicit) parameter,so it needs only one formal parameter.

//If simple, inline definition in.h fileinline ostream& operator<<(ostream& out, const Time& t){ t.Display(out); return out;}

Why?? out a reference parameter : ostream gets modified so must be passed back

t a const reference parameter : avoid overhead of copying a class object

return a reference to out: chain output operators

cout << t1 << endl << t2 << endl;

<< left-associative => operator<<(cout, t1) << endl << t2 << endl;

first function must return cout => cout << endl << t2 << endl;

=> operator<<(cout, endl) << t2 << endl;

Alternative:declare operator<< to be a friend of class Time

//in header filefriend ostream& operator<<(ostream& out, const Time& t);

//in implementation fileostream & operator<<(ostream & out, const Time & t){ out << t.myHours << ':' << (t.myMinutes < 10 ? "0" : "")

<< t.myMinutes << ' ' << t.myAMorPM << ".M. (" << t.myMilTime << " mil. time)";

return out;}

A function that a class declares as a friend is anon-member function to which

the class has granted permissionto access members in its private sections.

Note: Because a friend function is not a function member:

• definition not qualified with class name and scope operator (::)• receives the object on which it operates as a parameter• uses the dot operator to access the data members.

Friend Functions

Relational Operator<Specification:

Receives: Two Time objectsReturns: True if the first Time object is less than the second; false otherwise.

Should operator< be a member function?internal perspective: I compare myself with another Time object and

determine if I am less than that other objectexternal perspective: Two Time objects are compared to determine if the

first is less than the second.

OOP "I-can-do-it-myself" principle ( objects self-contained) use member functions whenever possible.

Rephrased specification:Receives: A Time object (and the current object implicitly)Returns: True if I (the Time object containing this function) am less than the

Time object received; false otherwise.

Relational Operator<// Internal perspective : add to Time.hclass Time{

public: // member functions .../***** Relational operators *****/

/* operator< determines if one Time is less than another TimeReceive: A Time t (and the current object implicitly)

Return: True if time represented by current object is < t.*/bool operator<(const Time & t);

...

}; // end of class declaration

inline bool Time::operator<(const Time & t){ return myMilTime < t.myMilTime; }

Caveat: Operator Overloading

Internal perspective may be too restrictive for completely consistent use

e.g. for some objects a & b of some class PromoteD

a < b; // ok: operator syntax,// equivalent to a.operator<(b)

b < a; // ok, same as b.operator(a)

a < 2; // ok, given a constructor that// promotes 2 to object of typepromoteD

// Statement then equivalent to a.operator<(2)

2 < a; // ERROR. 2.operator<(a) has no meaning

Syntactically confusing to application programmer tosupport a < 2 but disallow 2 < a.

use friends

Overloaded Operator as Friend

external perspective: permits a < 2 and 2 < a (if 2 can be promoted)

class Time{public: // member functions

.../* operator<Receive: Two Times t1 and t2Return: True if time t1 is less than time t2/*/friend bool Time::operator<(const Time& t1, const Time& t2);

...}; // end of class declaration

inline bool operator<(const Time& t1, const Time& t2){ return t1.myMilTime < t2.myMilTime; }

Redundant Declarations

class Time might be used in programs, libraries, etc. it could be included several times in the same file

e.g.,Program needs Time class, so it #includes "Time.h"Program also needs library Lib, so it #includes "Lib.h". . . but Lib.h also #includes "Time.h"

cause "redeclaration" errors during compiling.

How do we prevent the declarations in Time.h from beingincluded more than once in a file?

Conditional Compilation

Wrap the declarations in Time.h inside preprocessor directives#ifndef TIME Usually the name of the class in all caps#define TIME

: :#endif

The first directive tests to see whether the identifier TIME has been defined.

If defined:Proceed to second directive ( define TIME )Continue to the #endif and beyond.

If not defined:Preprocessor removes all code that followsuntil a #elsif, #else, of #endif directive encountered.