c++ data types. structs vs. classes c++ classes
Post on 20-Dec-2015
235 views
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.