Professional Documents
Culture Documents
Differences
1. C does not provide classes;
C++ provides both structs and classes
2. Members of a struct by default are public (can be
accessed outside the struct by using the dot operator.)
In C++ they can be declared to be private (cannot be
accessed outside the struct.)
3. Members of a class by default are private (cannot be
accessed outside the class) but can be explicitly
declared to be public.
3
C structs
Operations
Function
Members
Data
Members
Attributes
Declaring a Class
Common Forms:
class ClassName
{
// private by default
Declarations of private members
public:
Declarations of public members
};
class ClassName
{
public:
//"interface" of class given first
Declarations of public members
private:
Declarations of private members
};
Notes:
Data members are normally placed in the
private section of a class;
function members in the public section.
Some programmers prefer to put the
private section first:
- Using the default access for classes
- Can omit the private: specifier
Operations
public:
Function
Members
private:
Data
Members
Attributes
Other programmers put the public interface of the class first and the
hidden private details last. (In the text, the latter approach is used.)
Although not commonly done, a class may have several private and
public sections; the keywords private: and public: mark the
beginning of each.
6
"Accessors"
vs.
"Mutators"
(p. 91)
Implementation of a Class
Class declaration contains:
Declarations of data members
Prototypes (declarations) of function members
Definitions of function members are not usually placed in class declaration
Avoid cluttering up the interface
Definitions placed outside the class declaration must tell compiler where the
corresponding declaration/prototype is :
Use the scope operator :: which has the form
ClassName::ItemName
(the qualified or full name of ItemName.)
This applies also to constants and types
declared within a class.
e.g., Lab 3
11
Example:
See slide 19
class Something
{
public:
static const int CAPACITY = 100;
typedef double ArrayType[CAPACITY];
void Print(ArrayType a, int itsSize);
. . .
};
. . .
Something::ArrayType x = {0};
for (int i = 0; i < Something::CAPACITY; i++)
. . .
void Something::Print(Something::ArrayType a,
int itsSize)
{ . . . }
12
14
Note the
doc
15
16
int main()
{
Time mealTime;
mealTime.Set(5, 30, 'P');
cout << "We'll be eating at ";
mealTime.Display(cout);
cout << endl;
}
Execution:
We'll be eating at 5:30 P.M.
17
Object-Oriented Perspective
Procedural: Send object off to some function for processing
OOP:
18
Notes:
1. Member functions: "Inside" an object, so don't pass object to them as a
parameter. (They receive the object to be operated on implicitly, rather than
explicitly via a parameter.)
Non-member functions: "Outside" an object, so to operate on an object, they
must receive it via a parameter.
2. Public items must be qualified when referred to outside the class declaration:
ClassName::ItemName
Public constants are usually declared static so they are global class
properties that can be accessed by all objects of that class type rather than each
object having its own copy.
3. Simple member functions: Usually specified as inline functions.
This suggests to compiler to replace a function call with actual code of
the function with parameters replaced by arguments
saves overhead of function call.
Danger:
"Code Bloat"
19
//prototype
Interface
clutter
20
Mutators
How?
1. Use an if statement see Set()
2. Use assert(class_invar); (must #include <cassert>)
true
false
continue execution halt execution and display error message
21
App.
D.4
//----- Function to implement the Set operation ----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'))
{
. . .
}
else
{
char error[] = "*** Illegal initializer values ***\n";
throw error;
}
}
22
23
Class Constructors
Constructing an object consists of:
(1) allocating memory for the object, and
(2) initializing the object.
In our example, after the declaration
Time mealTime;
memory has been allocated for object mealTime and it's data
members have some default (perhaps "garbage") initial values.
Need to:
Specify initial values for mealTime
Provide default values to be used if no initial values are
specified.
This is the role of a class' constructor.
(Later, it will also allocate memory.)
24
25
Time();
private:
/********** Data Members **********/
. . .
26
27
Testing #1:
Time mealTime,
//default constructor
bedTime(11,30,'P'); //explicit-value constructor
Time();
Time(11,30,'P');
mealTime
myHours
myMinutes
myAMorPM
myMilTime
12
0
A
0
Function members
mealTime.Display(cout);
cout << endl;
bedTime.Display(cout);
cout << endl;
bedTime
myHours
11
myMinutes
30
myAMorPM
P
myMilTime 2330
Function members
Execution:
12:00 A.M. (0 mil. time)
11:30 P.M. (2330 mil. time)
28
Note: Any parameter with default argument must appear after all
parameters without default arguments.
29
Testing:
Time mealTime, t1(5), t2(5, 30), t3(5, 30, 'P');
Creates 4 Time objects:
12
0
A
0
5
0
A
500
mealTime.Display(cout);
cout << endl;
t1.Display(cout); cout << endl;
t2.Display(cout); cout << endl;
t3.Display(cout); cout << endl;
5
3
0A
530
5
3
0P
1730
Execution:
12:00 A.M. (0 mil. time)
5:00 A.M. (500 mil. time)
5:30 A.M. (530 mil. time)
5:30 P.M. (1730 mil. time)
30
Copy Operations
Two default copy operations are provided:
1. Copy in initialization (via copy constructor )
2. Copy in assignment (via assignment operator )
Each makes a raw (bitwise) copy of the memory allocated to the
data members of the object.
Note:
Type t = value;
Type t;
t = value;
This is OK
for now
31
Examples:
Time t = bedTime;
Time t(bedTime);
Both:
1. Allocate memory for t
2. Copy data members of bedTime so t is a copy of bedTime
11
30
P
2330
11
30
P
2330
In contrast:
Time t = Time(11, 30, 'P');
32
This is OK
for now
t = mealTime;
12
0
A
0
33
34
35
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)
37
as
cout.operator<<(t)
which means that operator<<(const Time &) would
member of class ostream (or cout be of type Time)
have to be a
and we can't (or don't want to) modify standard C++ classes.
Putting the prototype
ostream& operator<<(ostream & out, const Time& t);
38
39
. . .
} // end of class declaration
. . .
/* operator<< displays time in standard and military
format.
Receive:
ostream out and Time object t
Output:
time represented by Time object t
Pass back: ostream out with t inserted into it
Return:
out
*/
inline ostream & operator<<(ostream & out, const Time & t)
{
t.Display(out);
return out;
Note: No Time::
40
}
It's not a member function!
Note: No friend
{
out <<
<<
<<
<<
<<
return
}
41
Friend Functions
A function that a class declares as a friend is a
non-member function to which the class has granted
permission to access members in its private sections.
Note: Because a friend function is not a function member:
Don't qualify its definition with
class name and scope operator (::).
Don't put friend in definition.
It receives the object on which it operates as a parameter.
It uses the dot operator to access the data members.
42
43
44
However . . .
45
47
AddingIncrement/DecrementOperators
Specification:
Receives: A Time object (perhaps implicitly)
Returns: The Time object with minutes incremented by 1
minute.
Yes
Question: Should it be a member function?
Add to Time.h:
/***** Increment operator *****/
/* --- Advance() increments a Time by 1 minute.
Postcondition: The Time object has its minutes
incremented by 1.
-----------------------------------------------*/
void Advance();
48
AddtoTime.cpp:
//----- Function to implement Advance() ----void Time::Advance()
{
myMinutes++;
myHours += myMinutes / 60;
myMinutes %= 60; myHours %= 12;
if (myMilTime == 1159)
myAMorPM = 'P';
else if (myMilTime == 2359)
myAMorPM = 'A';
// else no change
myMilTime =
ToMilitary(myHours, myMinutes, myAMorPM);
}
49
++
We could replace Advance() with overloaded operator+
+().
Question: How do we distinguish between prefix ++ and
What's
postfix ++?
the
Solution: In C++, when the
differenc
Compiler encounters:
It looks for:
e?
Prefix ++:
operator++() with no
parameters
Postfix +
operator++(int) with one
+:
int parameter
(which is not used in the
definition.)
50
Redundant Declarations
Class Time might be used in different programs, libraries, etc., so 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
This can cause "redeclaration" errors during compiling.
How do we prevent the declarations in Time.h from being included
more than once in a file?
51
Conditional Compilation
Wrap the declarations in Time.h inside preprocessor directives.
(Preprocessor scans through file removing comments, #including files, and
processing other directives (which begin with #) before the file is passed to the
compiler.)
#ifndef TIME
#define TIME
:
:
#endif
The first directive tests to see whether the identifier TIME has been defined.
If not defined:
Proceed to second directive ( define TIME )
Continue to the #endif and beyond.
If defined:
Preprocessor removes all code that follows until a
#elsif, #else, or #endif directive encountered.
52