2021/8/8 Foundations | Member Functions and Privacy
https://ict.senecacollege.ca/~oop244/pages/content/cppst.html 1/11
ICT Home Outline Timeline Notes IPC Notes MySeneca Workshops Assignments Instructor
Software
Development
OOP244
Part B – Foundations
Member Functions and Privacy
Design member functions using logic constructs
Control accessibility to the data members of a class
Introduce the concept of an object’s empty state
“Because different structures can have member functions with the same name, we must specify the structure name when defining a
member function” (Stroustrup, 1997)
Member Functions | Privacy | Empty State | I/O Examples | Summary | Exercises
The primary concept of object-oriented programming is class encapsulation. Encapsulation incorporates within a class the
structure of data that its objects store and the logic that operates on that data. In other words, encapsulation creates a clean
interface between the class and its clients while hiding the implementation details from its clients. The C++ language describes
this logic in the form of functions that are members of the class. The data members of a class hold the information about the state
of its objects, while the member functions define the operations that query, modify and manage that state.
This chapter describes the C++ syntax for declaring member functions in a class definition, for defining the member functions in
the implementation file and for limiting accessibility to an object’s data.
MEMBER FUNCTIONS
The member functions of a class provide the communication links between client code and objects of the class. Client code calls
the member functions to access an object’s data and possibly to change that data.
We classify member functions into three mutually exclusive categories:
queries – also called accessor methods – report the state of the object
modifiers – also called mutator methods – change the state of the object
special – also called manager methods – create, assign and destroy an object
Every member function has direct access to the members of its class. Each member function receives information from the client
code through its parameters and passes information to the client code through its return value and possibly its parameters.
Adding a Member Function
Consider a Student type with the following definition
const int NG = 20;
struct Student {
int no; // student number
Welcome
Notes
Welcome to OO
Object Terminology
Modular Programming
Types Overloading
Dynamic Memory
Member Functions
Construction
Current Object
Member Operators
Class + Resources
Helper Functions
Input Output
Derived Classes
Derived Functions
Virtual Functions
Abstract Classes
Templates
Polymorphism
I/O Refinements
D C + Resources
Standards
Bibliography
Library Functions
ASCII Sequence
Operator Precedence
C++ and C
Workshops
Assignments
Handouts
Practice
Resources
https://ict.senecac.on.ca/
https://ict.senecacollege.ca/~oop244/index.html
http://www.senecacollege.ca/ssos/findwithoutsemester/oop244/sict
https://ict.senecacollege.ca/~oop244/pages/timeline.html
https://ict.senecacollege.ca/~oop244/pages/content/index.html
https://scs.senecac.on.ca/~ipc144/pages/content/index.html
https://my.senecacollege.ca/webapps/portal/frameset.jsp
https://ict.senecacollege.ca/~oop244/dynamic/workshops/index.html
https://ict.senecacollege.ca/~oop244/pages/assignments/index.html
https://ict.senecacollege.ca/~oop244/pages/instructors/index.html
https://ict.senecacollege.ca/~oop244/pages/content/cppst_p.html
https://ict.senecacollege.ca/~oop244/pages/welco.html
https://ict.senecacollege.ca/~oop244/pages/content/index.html
https://ict.senecacollege.ca/~oop244/pages/content/langu.html
https://ict.senecacollege.ca/~oop244/pages/content/objec.html
https://ict.senecacollege.ca/~oop244/pages/content/compi.html
https://ict.senecacollege.ca/~oop244/pages/content/rudim.html
https://ict.senecacollege.ca/~oop244/pages/content/dynam.html
https://ict.senecacollege.ca/~oop244/pages/content/cppst.html
https://ict.senecacollege.ca/~oop244/pages/content/ctors.html
https://ict.senecacollege.ca/~oop244/pages/content/membe.html
https://ict.senecacollege.ca/~oop244/pages/content/overl.html
https://ict.senecacollege.ca/~oop244/pages/content/deepc.html
https://ict.senecacollege.ca/~oop244/pages/content/nonme.html
https://ict.senecacollege.ca/~oop244/pages/content/custo.html
https://ict.senecacollege.ca/~oop244/pages/content/inher.html
https://ict.senecacollege.ca/~oop244/pages/content/dfunc.html
https://ict.senecacollege.ca/~oop244/pages/content/inclu.html
https://ict.senecacollege.ca/~oop244/pages/content/abstr.html
https://ict.senecacollege.ca/~oop244/pages/content/param.html
https://ict.senecacollege.ca/~oop244/pages/content/adhoc.html
https://ict.senecacollege.ca/~oop244/pages/content/basic.html
https://ict.senecacollege.ca/~oop244/pages/content/dclas.html
https://ict.senecacollege.ca/~oop244/pages/content/ansis.html
https://ict.senecacollege.ca/~oop244/pages/content/bibli.html
https://ict.senecacollege.ca/~oop244/pages/content/libraries.html
https://ict.senecacollege.ca/~oop244/pages/content/ascii.html
https://ict.senecacollege.ca/~oop244/pages/content/prece.html
https://ict.senecacollege.ca/~oop244/pages/content/c_cpp.html
https://ict.senecacollege.ca/~oop244/dynamic/workshops/index.html
https://ict.senecacollege.ca/~oop244/pages/assignments/index.html
https://ict.senecacollege.ca/~oop244/pages/handouts/index.html
https://ict.senecacollege.ca/~oop244/pages/practice/index.html
https://ict.senecacollege.ca/~oop244/pages/resources/index.html
2021/8/8 Foundations | Member Functions and Privacy
https://ict.senecacollege.ca/~oop244/pages/content/cppst.html 2/11
float grade[NG]; // grades
int ng; // number of grades filled
};
Function Declaration
To declare a member function to a class, we insert its prototype into the class definition.
For example, to add display() as a member to our Student type, we write:
struct Student {
int no;
float grade[NG];
int ng;
void display() const; // member function
};
The const qualifier identifies the member function as a query. A query does not change the state of its object. That is, this
query cannot change the value of no or any grade.
As a member function, display() has direct access to the data members (no and grade). There is no need to pass their
values as arguments to the function.
Function Definition
We define display() in the implementation file as follows:
void Student::display() const {
cout << no << ": \n"; for (int i = 0; i < ng; i++) cout << grade[i] << endl; } The definition consists of four elements: the Student:: prefix on the function name identifies it as a member of our Student type the empty parameter list - this function does not receive any values from the client code or return any values through the parameter list to the client code the const qualifier identifies this function as a query - this function cannot change any of the values of the object's data members the data members - the function accesses no and grade are defined outside the function's scope but within the class' scope, which encompasses the function's scope Calling a Member Function Client code calls a member function in the same way that an instance of a struct refers to one of its data members. The call consists of the object's identifier, followed by the . operator and then followed by the member function's identifier. For example, if harry is a Student object, we display its data by calling display() on harry: Student harry = {975, 78.9f, 69.4f}; harry.display(); // <== client call to the member function cout << endl; The object part of the function call (the part before the member selection operator) identifies the data that the function accesses. Scope of a Member Function The scope of a member function lies within the scope of its class. That is, a member function can access any other member within its class' scope. For example, a member function can access another member function directly: 2021/8/8 Foundations | Member Functions and Privacy https://ict.senecacollege.ca/~oop244/pages/content/cppst.html 3/11 struct Student { int no; float grade[NG]; int ng; void display() const; void displayNo() const; }; void Student::displayNo() const { cout << no << ": \n"; } void Student::display() const { displayNo(); // calls the member function defined above for (int i = 0; i < ng; i++) cout << grade[i] << endl; } Accessing Global Functions A member function can also access a function outside its class' scope. Consider the following global function definition: void displayNo() { cout << "Number...\n"; } Note that this definition does not include any scope resolution identifier. This global function shares the same identifier with one of the member functions, but does not introduce any conflict, since the client code calls each function using different syntax. displayNo(); // calls the global display function harry.displayNo(); // calls the member function on harry To access the global function from within the member function we apply the scope resolution operator: void Student::display() const { ::displayNo(); // calls the global function displayNo(); // calls the member function for (int i = 0; i < ng; i++) cout << grade[i] << endl; } PRIVACY Data privacy is central to encapsulation. Data members defined using the struct keyword are exposed to client code. Any client code can change the value of a data member. To limit accessibility to any member, the C++ language lets us hide that member within the class by identifying it as private. Well-designed object-oriented solutions expose to client code only those members that are the class's communication links. In a good design, the client code should not require direct access to any data that describes an object's state or any member function that performs internally directed operations. Accessibility Labels To prohibit external access to any member (data or function), we insert the label private into the definition of our class: private: private identifies all subsequent members listed in the class definition as inaccessible. To enable external access, we insert the label public: public: public identifies all subsequent members listed in the class definition as accessible. 2021/8/8 Foundations | Member Functions and Privacy https://ict.senecacollege.ca/~oop244/pages/content/cppst.html 4/11 For example, in order to hide the data members of each Student object expose the member function(s) of the Student type we insert the accessibility keywords as follows struct Student { private: int no; float grade[NG]; int ng; public: void display() const; }; Note that the keyword struct identifies a class that is public by default. class The keyword class identifies a class that is private by default. We use the keyword class to simplify the definition of a Student type: class Student { int no; float grade[NG]; int ng; public: void display() const; }; The class keyword is the common keyword in object-oriented programming, much more common than the struct keyword. (The C language does not support privacy and a derived type in C can only be a struct). Any attempt by the client code to access a private member generates a complier error: void foo(const Student& harry) { cout << harry.no; // ERROR - this member is private! } The function foo() can only access the data stored in harry indirectly through public member function display(). void foo(const Student& harry) { harry.display(); // OK } Modifying Private Data If the data members of a class are private, client code cannot initialize their values directly. We use a separate member function for this specific task. For example, to store data in Student objects, let us introduce a public modifier named set(): const int NG = 20; class Student { int no; float grade[NG]; int ng; public: 2021/8/8 Foundations | Member Functions and Privacy https://ict.senecacollege.ca/~oop244/pages/content/cppst.html 5/11 void set(int, const float*, int); void display() const; }; set() receives a student number, the address of an unmodifiable array of grades and the number of grades in that array from the client code and stores this information in the data members of the Student object: void Student::set(int sn, const float* g, int ng_) { ng = ng_ < NG ? ng_ : NG; no = sn; // store the Student number as received // store the grades as received within the available space for (int i = 0; i < ng; i++) grade[i] = g[i]; } Communications Links The set() and display() member functions are the only communication links to client code. Clients can call set() or display() on any Student object, but no client code can access the data stored within any Student object directly. For example, the compiler traps the following privacy breach: Student harry; float g[] = {78.9f, 69.4f}; harry.set(975, g, 2); harry.display(); cout << harry.no; // ERROR .no IS PRIVATE! EMPTY STATE Hiding all data members from client code gives us control over which data to accept, which data to reject and which data to expose. We can validate information incoming from client code before storing it in an object. If the data is invalid, we can reject it and store default values that identify the object's state as an empty state. Upgrading set() Let us upgrade our set() member function to validate incoming data only if the student number is positive-valued the grades are between 0 and 100 inclusive If any incoming data fails to meet one of these conditions, let us ignore all incoming data and store a value that places the object in an empty state. For instance, let us use a student number of 0 to identify an empty state: void Student::set(int sn, const float* g, int ng_) { int n = ng_ < NG ? ng_ : NG; bool valid = true; // assume valid input, check for invalid values if (sn < 1) valid = false; else for (int i = 0; i < n && valid; i++) valid = g[i] >= 0.0f && g[i] <= 100.0f; if (valid) { // accept the client's data no = sn; ng = n; for (int i = 0; i < n; i++) grade[i] = g[i]; } else { no = 0; // ignore the client's data, set an empty state 2021/8/8 Foundations | Member Functions and Privacy https://ict.senecacollege.ca/~oop244/pages/content/cppst.html 6/11 } } This validation logic ensures that either the data stored in any Student object is valid data or the object is in an empty state. Design Tip Select one data member to hold the special value that identifies an empty state. Then, to determine if an object is in an empty state, we only need to interrogate that data member. Upgrading display() To match this upgrade, we ensure that our display() member function executes gracefully if our object is in an empty state: void Student::display() const { if (no != 0) { cout << no << ":\n"; for (int i = 0; i < ng; i++) cout << grade[i] << endl; } else { cout << "no data available"; } } Looking Forward Although this upgrade validates data incoming from client code, our class definition still leaves the data in a Student object uninitialized before the first call from client code to set(). To address this deficiency, we will introduce a special member function in the chapter entitled Construction and Destruction. INPUT AND OUTPUT EXAMPLES The iostream type that represents the standard input and output objects, like cin and cout, provides member functions for controlling the conversion of characters from the input stream into data types stored in system memory and the conversion of data types stored in system memory into characters sent to the output stream. cin The cin object is an instance of the istream type. This object extracts a sequence of characters from the standard input stream, converts that sequence into a specified type and stores that type in system memory. The general expression for extracting characters from the standard input stream takes the form cin >> identifier
where >> is the extraction operator and identifier is the name of the destination variable.
For example,
int i;
char c;
double x;
char s[8];
cout << "Enter an integer,\n"
"a character,\n"
"a floating-point number and\n"
"a string : " << flush;
cin >> i;
cin >> c;
cin >> x;
cin >> s; // possible overflow
cout << "Entered " << i << ' '
<< c << ' ' << x << ' ' << s << endl;
Enter an integer,
a character,
a floating-point and
a string : 6 - 9.75 Harry
Entered 6 - 9.75 Harry
The cin object skips leading whitespace with numeric, string and character types (in the same way that scanf("%d"...),
scanf("%lf"...), scanf("%s"...) and scanf(" %c"...) skip whitespace in C).
https://ict.senecacollege.ca/~oop244/pages/content/ctros.html
2021/8/8 Foundations | Member Functions and Privacy
https://ict.senecacollege.ca/~oop244/pages/content/cppst.html 7/11
// Leading Whitespace
// leading.cpp
#include
using namespace std;
int main() {
char str[11];
cout << "Enter a string : " << endl;
cin >> str;
cout << "|" << str << "|" << endl;
}
Note: _ denotes space
Enter a string :
__abc
|abc|
cin treats whitespace in the input stream as a delimiter for numeric and string data types. For C-style null-terminated string
types, cin adds the null byte after the last non-whitespace character stored in memory:
// Trailing Whitespace
// trailing.cpp
#include
using namespace std;
int main() {
char str[11];
cout << "Enter a string : " << endl;
cin >> str;
cout << "|" << str << "|" << endl;
}
Note: _ denotes space
Enter a string :
__abc__
|abc|
The istream type supports the following member functions:
ignore(...) - ignores/discards character(s) from the input buffer
get(...) - extracts a character or a string from the input buffer
getline(...) - extracts a line of characters from the input buffer
For detailed descriptions of get() and getline(), see the chapter entitled More on Input and Output.
ignore
The ignore() member function extracts characters from the input buffer and discards them. ignore() does not skip leading
whitespace. Two versions of ignore() are available:
cin.ignore();
cin.ignore(2000, '\n');
The no-argument version discards a single character. The two-argument version removes and discards up to the specified number
of characters or up to the specified delimiting character, whichever occurs first and discards the delimiting character. The default
delimiter is end-of-file (not end-of-line).
cout
The cout object is an instance of the ostream type. An ostream object copies data from system memory into an output
stream; in copying, it converts the data in system memory into a sequence of characters.
The general expression for inserting data into the standard output stream takes the form
cout << identifier
where << is the insertion operator and identifier is the name of the variable or object that holds the data.
For example,
int i = 6;
char c = ' ';
double x = 9.75;
https://ict.senecacollege.ca/~oop244/pages/content/basic.html#ist
2021/8/8 Foundations | Member Functions and Privacy
https://ict.senecacollege.ca/~oop244/pages/content/cppst.html 8/11
char s[] = "Harry";
cout << i;
cout << c;
cout << x;
cout << c;
cout << s;
cout << endl;
cout << "Data has been written";
6 9.75 Harry
Data has been written
endl inserts a newline character into the stream and flushes the stream's buffer.
We may combine these expressions into a single statement that specifies multiple insertions:
int i = 6;
char c = ' ';
double x = 9.75;
char s[] = "Harry";
cout << i << c << x << c << s << endl;
cout << "Data has been written";
6 9.75 Harry
Data has been written
We call such repeated use of the insertion operator cascading.
The ostream type supports the following public member functions for formatting conversions:
width(int) - sets the field width to the integer received
fill(char) - sets the padding character to the character received
setf(...) - sets a formatting flag to the flag received
unsetf(...) - unsets a formatting flag for the flag received
precision(int) - sets the decimal precision to the integer received
width
The width(int) member function specifies the minimum width of the next output field:
// Field Width
// width.cpp
#include
using namespace std;
int main() {
int attendance = 27;
cout << "1234567890" << endl;
cout.width(10);
cout << attendance << endl;
cout << attendance << endl;
}
1234567890
27
27
width(int) applies only to the next field. Note how the field width for the first display of attendance is 10, while the field
width for the second display of attendance is just the minimum number of characters needed to display the value (2).
fill
The fill(char) member function defines the padding character. The output object inserts this character into the stream
wherever text occupies less space than the specified field width. The default fill character is ' ' (space). To pad a field with
'*''s, we add:
// Padding
// fill.cpp
#include
using namespace std;
int main() {
int attendance = 27;
cout << "1234567890" << endl;
cout.fill('*'); 1234567890
2021/8/8 Foundations | Member Functions and Privacy
https://ict.senecacollege.ca/~oop244/pages/content/cppst.html 9/11
cout.width(10);
cout << attendance << endl;
}
********27
The padding character remains unchanged, until we reset it.
setf, unsetf
The setf() and unsetf() member functions control formatting and alignment. Their control flags include:
Control Flag Result
ios::fixed ddd.ddd
ios::scientific d.ddddddEdd
ios::left align left
ios::right align right
The scope resolution (ios::) on these flags identifies them as part of the ios class.
setf, unsetf - Formatting
The default format in C++ is general format, which outputs data in the simplest, most succinct way possible (1.34, 1.345E10,
1.345E-20). To output a fixed number of decimal places, we select fixed format. To specify fixed format, we pass the
ios::fixed flag to setf():
// Fixed Format
// fixed.cpp
#include
using namespace std;
int main() {
double pi = 3.141592653;
cout << "1234567890" << endl;
cout.width(10);
cout.setf(ios::fixed);
cout << pi << endl;
}
1234567890
3.141593
Format settings persist until we change them. To unset fixed format, we pass the ios::fixed flag to the unsetf() member
function:
// Unset Fixed Format
// unsetf.cpp
#include
using namespace std;
int main() {
double pi = 3.141592653;
cout << "1234567890" << endl;
cout.width(10);
cout.setf(ios::fixed);
cout << pi << endl;
cout.unsetf(ios::fixed);
cout << pi << endl;
}
1234567890
3.141593
3.14159
To specify scientific format, we pass the ios::scientific flag to the setf() member function:
// Scientific Format
// scientific.cpp
#include
using namespace std;
int main() {
2021/8/8 Foundations | Member Functions and Privacy
https://ict.senecacollege.ca/~oop244/pages/content/cppst.html 10/11
double pi = 3.141592653;
cout << "12345678901234" << endl;
cout.width(14);
cout.setf(ios::scientific);
cout << pi << endl;
}
12345678901234
3.141593e+00
To turn off scientific format, we pass the ios::scientific flag to the unsetf() member function.
setf, unsetf - Alignment
The default alignment is right-justified.
To specify left-justification, we pass the ios::left flag to the setf() member function:
// Left Justified
// left.cpp
#include
using namespace std;
int main() {
double pi = 3.141592653;
cout << "1234567890" << endl;
cout.width(10);
cout.fill('?');
cout.setf(ios::left);
cout << pi << endl;
}
1234567890
3.14159???
To turn off left-justification, we pass the ios::left flag to the unsetf() member function:
cout.unsetf(ios::left);
precision
The precision() member function sets the precision of subsequent floating-point fields. The default precision is 6 units.
General, fixed, and scientific formats implement precision differently. General format counts the number of significant digits.
Scientific and fixed formats count the number of digits following the decimal point.
For a precision of 2 under general format, we write
// Precision
// precison.cpp
#include
using namespace std;
int main() {
double pi = 3.141592653;
cout << "1234567890" << endl;
cout.setf(ios::fixed);
cout.width(10);
cout.precision(2);
cout << pi << endl;
}
1234567890
3.14
The precision setting applies to the output of all subsequent floating-point values until we change it.
Student Example
The code snippet listed on the left produces the output listed on the right
void Student::display() const {
if (no > 0) {
cout << no << ":\n";
cout.setf(ios::fixed); 975:
2021/8/8 Foundations | Member Functions and Privacy
https://ict.senecacollege.ca/~oop244/pages/content/cppst.html 11/11
cout.precision(2);
for (int i = 0; i < ng; i++) {
cout.width(6);
cout << grade[i] << endl;
}
cout.unsetf(ios::fixed);
cout.precision(6);
} else {
cout << "no data available" << endl;
}
}
78.90
69.40
SUMMARY
object-oriented classes may contain both data members and member functions
the keyword private identifies subsequent members as inaccessible to any client
the keyword public identifies subsequent members as accessible to any client
data members hold the information about an object's state
member functions describe the logic that an object performs on its data members
a query reports the state of an object without changing its state
a modifier changes the state of an object
an empty state is the set of data values that identifies the absence of valid data in an object
a field width setting only holds for the next field
all settings other than a field width setting persist until changed
precision has different meanings under general, scientific, and fixed formats
EXERCISES
Complete the Handout on Member Functions and Privacy
Complete the Workshop on Classes and Privacy
print this page Top
Previous: Dynamic Mmeory Next: Construction and Destruction
ICT Home Outline Timeline
Notes IPC Notes MySeneca Workshops Assignments Instructor
Designed by Chris Szalwinski Copying From This Site Last Modified: 05/20/2017 11:50
https://ict.senecacollege.ca/~oop244/pages/handouts/h2.html
https://ict.senecacollege.ca/~oop244/dynamic/workshops/w3.html
https://ict.senecacollege.ca/~oop244/pages/content/cppst_p.html
https://ict.senecacollege.ca/~oop244/pages/content/dynam.html
https://ict.senecacollege.ca/~oop244/pages/content/ctors.html
https://ict.senecac.on.ca/
https://ict.senecacollege.ca/~oop244/index.html
http://www.senecacollege.ca/ssos/findwithoutsemester/oop244/sict
https://ict.senecacollege.ca/~oop244/pages/timeline.html
https://ict.senecacollege.ca/~oop244/pages/content/index.html
https://scs.senecac.on.ca/~ipc144/pages/content/index.html
https://my.senecacollege.ca/webapps/portal/frameset.jsp
https://ict.senecacollege.ca/~oop244/dynamic/workshops/index.html
https://ict.senecacollege.ca/~oop244/pages/assignments/index.html
https://ict.senecacollege.ca/~oop244/pages/instructors/index.html
https://ict.senecacollege.ca/~oop244/pages/copyright.html
http://creativecommons.org/licenses/by/2.5/ca/