Objectoriented Programming In C Sourav Sahay instant download
Objectoriented Programming In C Sourav Sahay instant download
download
https://ebookbell.com/product/objectoriented-programming-in-c-
sourav-sahay-55234334
https://ebookbell.com/product/objectoriented-programming-in-c-nicolai-
m-josuttis-46086084
https://ebookbell.com/product/objectoriented-programming-in-c-7th-
print-with-corrections-lafore-21984516
https://ebookbell.com/product/object-oriented-programming-in-c-4th-
edition-e-balagurusamy-33057582
https://ebookbell.com/product/object-oriented-programming-in-c-1st-
edition-rajesh-k-shukla-231674382
Object Oriented Programming In C 2009th Edition Gt Thampi
https://ebookbell.com/product/object-oriented-programming-in-c-2009th-
edition-gt-thampi-231682510
https://ebookbell.com/product/objectoriented-programming-in-c-
succinctly-20191205-sander-rossel-36135060
https://ebookbell.com/product/objectoriented-programming-in-c-4th-
edition-robert-lafore-11950040
https://ebookbell.com/product/learning-objectoriented-programming-
in-c-50-b-m-harwani-4954158
https://ebookbell.com/product/an-introduction-to-objectoriented-
programming-in-c-with-applications-in-computer-graphics-2nd-edition-
graham-m-seed-beng-4198618
Object Oriented
Programming with
C++
SECOND EDITION
Sourav Sahay
Lead Consultant
Capgemini
Detroit, Michigan
1
3
Oxford University Press is a department of the University of Oxford.
It furthers the University’s objective of excellence in research, scholarship,
and education by publishing worldwide. Oxford is a registered trade mark of
Oxford University Press in the UK and in certain other countries.
Published in India by
Oxford University Press
YMCA Library Building, 1 Jai Singh Road, New Delhi 110001, India
ISBN-13: 978-0-19-806530-2
ISBN-10: 0-19-806530-2
C++ made its advent in the early 1980s and enabled programmers to write their programs
the object-oriented way. For this reason, the language quickly gained popularity and became
a programming language of choice. Despite the development of a number of competing
object-oriented languages including Java, C++ has successfully maintained its position of
popularity.
C++ starts where C stops. C++ is a superset of C. All the language features of C language
appear in C++ with little or no modi¿cation. Over and above such features, C++ provides a
number of extra features, which provide the language its object-oriented character.
The continued popularity of C++ has led to considerable literature. Innumerable books, journals,
magazines, and articles have been written on C++. So, why another book on C++?
The aim of the book is to thoroughly explain all aspects of the language constructs provided
by C++. While doing full justice to the commonly explained topics of C++, the book does
not neglect the advanced and new concepts of C++ that are not widely taught.
This book is a power-packed instruction guide for Object-Oriented Programming and C++.
The purpose of this book is two-fold:
x To clarify the fundamentals of the Object-Oriented Programming System
x To provide an in-depth treatment of each feature and language construct of C++
This book emphasizes the Object-Oriented Programming System—its bene¿ts and its
superiority over the conventional Procedure-Oriented Programming System.
This book starts directly with C++ since the common features of C and C++ are anyway
covered in books on C language. Each feature of C++ is covered from the practical point of
view. Instead of brief introductions, this book gives an in-depth explanation of the rationale
and proper use of each object-oriented feature of C++.
To help the readers assimilate the large volume of knowledge contained in this book, an
adequate number of example programs, well-designed diagrams, and analogies with the real
world have been given. Some program examples given in this book are abstract in nature to
help readers focus on the concept being discussed.
Preface to the First Edition vii
Acknowledgements
First, I thank my parents for teaching me a number of valuable lessons of life including the
value of hardwork and the value of good education (neither of which I have learnt yet!). I also
thank my wife Madhvi for her patience, her encouragement, and also for having tolerated my
long periods of silence and temper tantrums! Thanks (rather apologies) to my little daughters,
Surabhi and Sakshi, who tolerated Papa’s frequent refusals to take them on outings.
I thank Dr David Mulvaney and Dr Sekharjit Datta of the University of Loughborough for
their valuable guidance, encouragement, and inspiration. My teachers always encouraged me
to think big and to think independently. My sincerest gratitude to each one of them.
The editorial team of Oxford University Press deserves my heartfelt thanks for their
guidance and for their timely reminders about the deadlines I would have de¿nitely missed
otherwise!
Feedback about the book is most welcome. Readers are requested and encouraged to send
their feedback to the author’s mail id [email protected].
Sourav Sahay
Preface to the Second Edition
x Expanded glossary.
x Accompanying CD contains all the program codes given in the text.
Key Features
x Simple and concise language eases the understanding of complex concepts that have
made C++ powerful but enigmatic.
x Plenty of solved examples with complete program listings and test cases to reinforce
learning.
x Review questions and program writing exercises at the end of each chapter to provide
additional practice.
x Self-tests at the end of the book to prepare the students for examinations.
conversions. New style casts for implementing type conversions are explained next. This
chapter ends with a treatment of run time type information (RTTI).
Chapter 9 explains and illustrates the most important data structures—linked lists and trees.
It includes full-Àedged programs that can be used to create various data structures.
Chapter 10 contains a detailed description of templates. The importance of function
templates and class templates and their utilization in code reuse is explained. This chapter
also provides an overview of the Standard Template Library (STL) of C++.
Chapter 11 explains the concept of exception handling. It begins with a section on
conventional methods and their drawbacks. This is followed by an explanation of the try-catch-
throw mechanism provided by C++ and its superiority over the conventional methods.
The appendices in the book include a case study, comparison of C++ with C, comparison
of C++ with Java, an overview of object-oriented analysis and design, and self tests.
Acknowledgements
The blessings of my parents continue to give me the courage I need to overcome the obstacles
that are associated with dif¿cult ventures like writing books. Every achievement of my life,
including this book, is because of the valuable education they gave me early in my life. Thanks
to my wife Madhvi against whose wishes I decided to spend most of the weekends over the
last 2 years on my laptop writing this edition. My daughters Surabhi and Sakshi continue to
inspire and motivate me.
Thanks to Professor Shanmuka Swamy, Assistant Professor in the Sridevi Institute of
Engineering and Technology, Tumkur, for pointing out a couple of printing mistakes in the
¿rst edition. These have been corrected.
The editorial staff members of the Oxford University Press deserve a special mention for
its support and prompt responses.
Please continue to send your valuable feedback and questions to my e-mail id
[email protected].
Sourav Sahay
Brief Contents
Detailed Contents xi
1. Introduction to C++ 1
2. Classes and Objects 31
3. Dynamic Memory Management 78
4. Constructors and Destructors 92
5. Inheritance 117
6. Virtual Functions and Dynamic Polymorphism 153
7. Stream and File Handling 172
8. Operator Overloading, Type Conversion, New Style Casts, and RTTI 211
9. Data Structures 283
10. Templates 372
11. Exception Handling 393
Bibliography 460
Index 461
Detailed Contents
1. Introduction to C++ 1
1.1 A Review of Structures 1
1.1.1 The Need for Structures 1
1.1.2 Creating a New Data Type Using Structures 4
1.1.3 Using Structures in Application Programs 5
1.2 Procedure-Oriented Programming Systems 5
1.3 Object-Oriented Programming Systems 7
1.4 Comparison of C++ with C 8
1.5 Console Input/Output in C++ 9
1.5.1 Console Output 9
1.5.2 Console Input 12
1.6 Variables in C++ 13
1.7 Reference Variables in C++ 14
1.8 Function Prototyping 19
1.9 Function Overloading 21
1.10 Default Values for Formal Arguments of Functions 23
1.11 Inline Functions 25
5. Inheritance 117
5.1 Introduction 117
5.1.1 Effects of Inheritance 118
5.1.2 Bene¿ts of Inheritance 120
5.1.3 Inheritance in Actual Practice 120
5.1.4 Base Class and Derived Class Objects 121
5.1.5 Accessing Members of the Base Class in the Derived Class 121
5.2 Base Class and Derived Class Pointers 122
5.3 Function Overriding 127
5.4 Base Class Initialization 129
5.5 Protected Access Speci¿er 132
5.6 Deriving by Different Access Speci¿ers 133
5.6.1 Deriving by the Public Access Speci¿er 133
5.6.2 Deriving by the Protected Access Speci¿er 135
5.6.3 Deriving by the Private Access Speci¿er 136
5.7 Different Kinds of Inheritance 139
5.7.1 Multiple Inheritance 139
5.7.2 Ambiguities in Multiple Inheritance 141
Detailed Contents xiii
8. Operator Overloading, Type Conversion, New Style Casts, and RTTI 211
8.1 Operator Overloading 211
8.1.1 Overloading Operators—The Syntax 212
8.1.2 Compiler Interpretation of Operator-Overloading Functions 214
8.1.3 Overview of Overloading Unary and Binary Operators 216
8.1.4 Operator Overloading 216
8.1.5 Rules for Operator Overloading 219
8.2 Overloading Various Operators 221
8.2.1 Overloading Increment and Decrement Operators
(Pre¿x and Post¿x) 221
8.2.2 Overloading Unary Minus and Unary Plus Operator 224
8.2.3 Overloading Arithmetic Operators 225
8.2.4 Overloading Relational Operators 230
8.2.5 Overloading Assignment Operator 234
8.2.6 Overloading Insertion and Extraction Operators 240
8.2.7 Overloading new and delete Operators 244
8.2.8 Overloading Subscript Operator 261
8.2.9 Overloading Pointer-to-member (->) Operator (Smart Pointer) 265
8.3 Type Conversion 267
8.3.1 Basic Type to Class Type 267
8.3.2 Class Type to Basic Type 268
8.3.3 Class Type to Class Type 269
8.4 New Style Casts and the typeid Operator 271
8.4.1 dynamic_cast Operator 271
8.4.2 static_cast Operator 275
8.4.3 reinterpret_cast Operator 276
8.4.4 const_cast Operator 276
8.4.5 typeid Operator 277
Bibliography 460
Index 461
1 Introduction to C++
O This chapter introduces the reader to the fundamentals of object-oriented programming systems
(OOPS).
V The chapter begins with an overview of structures, the reasons for their inclusion as a
E language construct in C language, and their role in procedure-oriented programming systems.
Use of structures for creating new data types is described. Also, the drawbacks of structures
R and the development of OOPS are elucidated.
The middle section of the chapter explains OOPS, supplemented with suitable examples
V and analogies to help in understanding this tricky subject.
I The concluding section of the chapter includes a study of a number of new features that are
implemented by C++ compilers but do not fall under the category of object-oriented features.
E (Language constructs of C++ that implement object-oriented features are dealt with in the
W next chapter.)
Here ‘d’, ‘m’, and ‘y’ represent the day of the month, the month, and the year, respectively.
Observe carefully. Although these three variables are not grouped together in the code, they
actually belong to the same group. The value of one variable may inÀuence the value of the
other two. In order to understand this clearly, consider a function next_day() that accepts
the addresses of the three integers that represent a date and changes their values to represent
the next day. The prototype of this function will be
void next_day(int *,int *,int *); //function to calculate
//the next day
2 Object-Oriented Programming with C++
Suppose,
d=1;
m=1;
y=2002; //1st January, 2002
Now, if we write
next_day(&d,&m,&y);
‘d’ will become 2, ‘m’ will remain 1, and ‘y’ will remain 2002.
But if
d=28;
m=2;
y=1999; //28th February, 1999
‘d’ will become 1, ‘m’ will become 3, and ‘y’ will remain 1999.
Again, if
d=31;
m=12;
y=1999; //31st December, 1999
‘d’ will become 1, ‘m’ will become 1, and ‘y’ will become 2000.
As you can see, ‘d’, ‘m’, and ‘y’ actually belong to the same group. A change in the value
of one may change the value of the other two. But there is no language construct that actually
places them in the same group. Thus, members of the wrong group may be accidentally sent
to the function (Listing 1.1)!
As can be observed in Listing 1.1, there is nothing in the language itself that prevents the
wrong set of variables from being sent to the function. Moreover, integer-type variables that
are not meant to represent dates might also be sent to the function!
Let us try arrays to solve the problem. Suppose the next_day() function accepts an array
as a parameter. Its prototype will be
void next_day(int *);
The values of ‘date[0]’, ‘date[1]’, and ‘date[2]’ will be correctly set to 1, 3, and 1999,
respectively. Although this method seems to work, it certainly appears unconvincing. After
all any integer array can be passed to the function, even if it does not necessarily represent
a date. There is no data type of date itself. Moreover, this solution of arrays will not work if
the variables are not of the same type. The solution to this problem is to create a data type
called date itself using structures
struct date //a structure to represent dates
{
int d, m, y;
};
Now, the next_day() function will accept the address of a variable of the structure date
as a parameter. Accordingly, its prototype will be as follows:
void next_day(struct date *);
‘d1.d’, ‘d1.m’, and ‘d1.y’ will be correctly set to 1, 3, and 1999, respectively. Since the
function takes the address of an entire structure variable as a parameter at a time, there is no
chance of variables of the different groups being sent to the function.
Structure is a programming construct in C that allows us to put together variables that
should be together.
Library programmers use structures to create new data types. Application programs and
other library programs use these new data types by declaring variables of this data type.
struct date d1;
They call the associated functions by passing these variables or their addresses to them.
d1.d=31;
d1.m=12;
d1.y=2003;
next_day(&d1);
Finally, they use the resultant value of the passed variable further as per requirements.
printf(“The next day is: %d/%d/%d\n”, d1.d, d1.m, d1.y);
Output
The next day is: 01/01/2004
4 Object-Oriented Programming with C++
Step 2: As shown in Listing 1.4, put the de¿nition of the associated functions in a source
code and create a library.
/*Beginning of date.c*/
/*This file contains the definitions of the associated
functions*/
#include “date.h”
void next_day(struct date * p)
{
//calculate the date that immediately follows the one
//represented by *p and set it to *p.
}
void get_sys_date(struct date * p)
{
//determine the current system date and set it to *p
}
/*
Definitions of other useful and relevant functions to work upon variables
of the date structure
*/
/*End of date.c*/
Step 3: Provide the header ¿le and the library, in whatever media, to other programmers who
want to use this new data type.
Creation of a structure and creation of its associated functions are two separate steps that
together constitute one complete process.
Introduction to C++ 5
Step 2: Declare variables of the new data type in the source code.
/*Beginning of dateUser.c*/
#include“date.h”
void main( )
{
struct date d;
. . . .
. . . .
}
/*End of dateUser.c*/
Step 3: As shown in Listing 1.5, embed calls to the associated functions by passing these
variables in the source code.
/*Beginning of dateUser.c*/
#include“date.h”
void main()
{
struct date d;
d.d=28;
d.m=2;
d.y=1999;
next_day(&d);
. . . .
. . . .
}
/*End of dateUser.c*/
In the procedure-oriented programming system, procedures are dissociated from data and
are not a part of it. Instead, they receive structure variables or their addresses and work upon
them. The code design is centered around procedures. While this may sound obvious, this
programming pattern has its drawbacks.
The drawback with this programming pattern is that the data is not secure. It can be
manipulated by any procedure. Associated functions that were designed by the library
programmer do not have the exclusive rights to work upon the data. They are not a part of
the structure de¿nition itself. Let us see why this is a problem.
Suppose the library programmer has de¿ned a structure and its associated functions as
described above. Further, in order to perfect his/her creation, he/she has rigorously tested
the associated functions by calling them from small test applications. Despite his/her best
efforts, he/she cannot be sure that an application that uses the structure will be bug free. The
application program might modify the structure variables, not by the associated function he/
she has created, but by some code inadvertently written in the application program itself.
Compilers that implement the procedure-oriented programming system do not prevent
unauthorized functions from accessing/manipulating structure variables.
Now, let us look at the situation from the application programmer’s point of view. Consider
an application of around 25,000 lines (quite common in the real programming world), in
which variables of this structure have been used quite extensively. During testing, it is found
that the date being represented by one of these variables has become 29th February 1999!
The faulty piece of code that is causing this bug can be anywhere in the program. Therefore,
debugging will involve a visual inspection of the entire code (of 25000 lines!) and will not
be limited to the associated functions only.
The situation becomes especially grave if the execution of the code that is likely to corrupt
the data is conditional. For example,
if(<some condition>)
d.m++; //d is a variable of date structure… d.m may
//become 13!
The condition under which the bug-infested code executes may not arise during testing.
While distributing his/her application, the application programmer cannot be sure that it would
run successfully. Moreover, every new piece of code that accesses structure variables will
have to be visually inspected and tested again to ensure that it does not corrupt the members
of the structure. After all, compilers that implement procedure-oriented programming systems
do not prevent unauthorized functions from accessing/manipulating structure variables.
Let us think of a compiler that enables the library programmer to assign exclusive rights to
the associated functions for accessing the data members of the corresponding structure. If this
happens, then our problem is solved. If a function which is not one of the intended associated
functions accesses the data members of a structure variable, a compile-time error will result.
To ensure a successful compile of his/her application code, the application programmer will
be forced to remove those statements that access data members of structure variables. Thus,
the application that arises out of a successful compile will be the outcome of a piece of code
that is free of any unauthorized access to the data members of the structure variables used
therein. Consequently, if a run-time error arises, attention can be focused on the associated
library functions.
It is the lack of data security of procedure-oriented programming systems that led to object-
oriented programming systems (OOPS). This new system of programming is the subject of
our next discussion.
Introduction to C++ 7
a variable of the new structure. For this, the address/name of a variable of the new structure
is passed to the associated functions of the existing structure.
In inheritance, data and interface may both be inherited. This is expected as data and
interface complement each other. The parent structure can be given the general common
characteristics while its child structures can be given the more speci¿c characteristics. This
allows code reusability by keeping the common code in a common place—the base structure.
Otherwise, the code would have to be replicated in all of the child structures, which will
lead to maintenance nightmares. Inheritance also enables code extensibility by allowing
the creation of new structures that are better suited to our requirements as compared to the
existing structures.
Polymorphism, as the name suggests, is the phenomena by virtue of which the same entity
can exist in two or more forms. In OOPS, functions can be made to exhibit polymorphic
behaviour. Functions with different set of formal arguments can have the same name.
Polymorphism is of two types: static and dynamic. We will understand how this feature enables
C++ programmers to reuse and extend existing code in the subsequent chapters.
/*Beginning of Date.h*/
class Date //class instead of structure
{
private:
int d,m,y;
public:
Date();
void get_sys_date(); //associated functions appear
//within the class definition
void next_day();
};
/*End of Date.h*/
The following differences can be noticed between Date structure in C (Listing 1.3) and C++
(Listing 1.6):
x The keyword class has been used instead of struct.
x Two new keywords—private and public—appear in the code.
x Apart from data members, the class constructor also has member functions.
x A function that has the same name as the class itself is also present in the class. Incidentally,
it has no return type specified. This is the class constructor and is discussed in Chapter 4
of this book.
Introduction to C++ 9
The next chapter contains an in-depth study of the above class construct. It explains the
meaning and implications of this new feature. It also explains how this and many more
new features implement the features of OOPS, such as data hiding, data encapsulation, data
abstraction, and a guaranteed initialization of data. However, before proceeding to Chapter
2, let us digress slightly and study the following:
x Console input/output in C++
x Some non-object-oriented features provided exclusively in C++ (reference variables,
function overloading, default arguments, inline functions)
Remember that C++ program ¿les have the extension ‘.cpp’ or ‘.C’. The former extension
is normally used for Windows or DOS-based compilers while the latter is normally used
for UNIX-based compilers. The compiler’s manual can be consulted to ¿nd out the exact
extension.
/*Beginning of cout.cpp*/
#include<iostream.h>
void main()
{
int x;
x=10;
cout<<x; //outputting to the console
}
/*End of cout.cpp*/
Output
10
The third statement in the main() function (Listing 1.7) needs to be understood.
cout (pronounce see-out) is actually an object of the class ostream_withassign (you can
think of it as a variable of the structure ostream_withassign). It stands as an alias for the
console output device, that is, the monitor (hence the name).
The << symbol, originally the left shift operator, has had its de¿nition extended in C++.
In the given context, it operates as the insertion operator. It is a binary operator. It takes
two operands. The operand on its left must be some object of the ostream class. The operand
on its right must be a value of some fundamental data type. The value on the right side of
the insertion operator is ‘inserted’ (hence the name) into the stream headed towards the
device associated with the object on the left. Consequently, the value of ‘x’ is displayed on
the monitor.
The ¿le iostream.h needs to be included in the source code to ensure successful compilation
because the object cout and the insertion operator have been declared in that ¿le.
10 Object-Oriented Programming with C++
Another object endl allows us to insert a new line into the output stream. Listing 1.8
illustrates this.
/*Beginning of endl.cpp*/
#include<iostream.h>
void main()
{
int x,y;
x=10;
y=20;
cout<<x;
cout<<endl; //inserting a new line by endl
cout<<y;
}
/*End of endl.cpp*/
Output
10
20
One striking feature of the insertion operator is that it works equally well with values of
all fundamental types as its right-hand operand. It does not need the format speci¿ers that are
needed in the printf() family of functions. Listing 1.9 exempli¿es this.
/*Beginning of cout.cpp*/
#include<iostream.h>
void main()
{
int iVar;
char cVar;
float fVar;
double dVar;
char * cPtr;
iVar=10;
cVar=‘x’;
fVar=2.3;
dVar=3.14159;
cPtr=“Hello World”;
cout<<iVar;
cout<<endl;
cout<<cVar;
cout<<endl;
cout<<fVar;
cout<<endl;
cout<<dVar;
cout<<endl;
cout<<cPtr;
cout<<endl;
}
/*End of cout.cpp*/
Introduction to C++ 11
Output
10
x
2.3
3.14159
Hello World
Just like the arithmetic addition operator, it is possible to cascade the insertion operator.
Listing 1.10 is a case in point.
/*Beginning of coutCascade.cpp*/
#include<iostream.h>
void main()
{
int x;
float y;
x=10;
y=2.2;
cout<<x<<endl<<y; //cascading the insertion operator
}
/*End of coutCascade.cpp*/
Output
10
2.2
It is needless to say that we can pass constants instead of variables as operands to the insertion
operator, as shown in Listing 1.11.
/*Beginning of coutMixed.cpp*/
#include<iostream.h>
void main()
{
cout<<10<<endl<<“Hello World\n”<<3.4;
}
/*End of coutMixed.cpp*/
Ouput
10
Hello World
3.4
In Listing 1.11, note the use of the new line character in the string that is passed as one of the
operands to the insertion operator.
It was mentioned in the beginning of this section that cout is an object that is associated
with the console. Hence, if it is the left-hand side operand of the insertion operator, the
value on the right is displayed on the monitor. You will learn in the chapter on stream handling
that it is possible to pass objects of some other classes that are similarly associated with disk
12 Object-Oriented Programming with C++
¿les as the left-hand side operand to the insertion operator. In such cases, the values on
the right get stored in the associated ¿les.
/*Beginning of cin.cpp*/
#include<iostream.h>
void main()
{
int x;
cout<<“Enter a number: ”;
cin>>x; //console input in C++
cout<<“You entered: ”<<x;
}
/*End of cin.cpp*/
Output
Enter a number: 10<enter>
You entered: 10
The third statement in the main() function of Listing 1.12 needs to be understood.
cin (pronounce see-in) is actually an object of the class istream_withassign (you can
think of it as a variable of the structure istream_withassign). It stands as an alias for the
console input device, that is, the keyboard (hence the name).
The >> symbol, originally the right-shift operator, has had its de¿nition extended in C++.
In the given context, it operates as the extraction operator. It is a binary operator and takes
two operands. The operand on its left must be some object of the istream_withassign class.
The operand on its right must be a variable of some fundamental data type. The value for the
variable on the right side of the extraction operator is extracted (hence the name) from the
stream originating from the device associated with the object on the left. Consequently, the
value of ‘x’ is obtained from the keyboard.
The ¿le iostream.h needs to be included in the source code to ensure successful compilation
because the object cin and the extraction operator have been declared in that ¿le.
Again, just like the insertion operator, the extraction operator works equally well
with variables of all fundamental types as its right-hand operand. It does not need the format
speci¿ers that are needed in the scanf() family of functions. Listing 1.13 exempli¿es this.
/*Beginning of cin.cpp*/
#include<iostream.h>
void main()
{
int iVar;
Introduction to C++ 13
char cVar;
float fVar;
cout<<“Enter a whole number: ”;
cin>>iVar;
cout<<“Enter a character: ”;
cin>>cVar;
cout<<“Enter a real number: ”;
cin>>fVar;
cout<<“You entered: ”<<iVar<<“ ”<<cVar<<“ ”<<fVar;
}
/*End of cin.cpp*/
Output
Enter a whole number: 10<enter>
Enter a character: x<enter>
Enter a real number: 2.3<enter>
You entered: 10 x 2.3
Just like the insertion operator, it is possible to cascade the extraction operator. Listing
1.14 is a case in point.
/*Beginning of cinCascade.cpp*/
#include<iostream.h>
void main()
{
int x,y;
cout<<“Enter two numbers\n”;
cin>>x>>y; //cascading the extraction operator
cout<<“You entered ”<<x<<“ and ”<<y;
}
/*End of cinCascade.cpp*/
Output
Enter two numbers
10<enter>
20<enter>
You entered 10 and 20
It was mentioned in the beginning of this section that cin is an object that is associated with
the console. Hence, if it is the left-hand side operand of the extraction operator, the variable
on the right gets its value from the keyboard. You will learn in the chapter on stream handling
that it is possible to pass objects of some other classes that are similarly associated with disk
¿les as the left-hand side operand to the extraction operator. In such cases, the variable on
the right gets its value from the associated ¿les.
#include<iostream.h>
void main()
{
int x;
x=10;
cout<<“Value of x= ”<<x<<endl;
int * iPtr; //declaring a variable in the middle of a
//function
iPtr=&x;
cout<<“Address of x= ”<<iPtr<<endl;
}
Output
Value of x=10
Address of x= 0x21878163
Especially, you must remember that the expression on the left of the assignment operator
must be capable of being evaluated to a valid address at which data can be written.
Now, let us study reference variables. A reference variable is nothing but a reference for
an existing variable. It shares the memory location with an existing variable. The syntax for
declaring a reference variable is as follows:
<data-type> & <ref-var-name>=<existing-var-name>;
For example, if ‘x’ is an existing integer-type variable and we want to declare iRef as a
reference to it the statement is as follows:
int & iRef=x;
iRef is a reference to ‘x’. This means that although iRef and ‘x’ have separate entries in the
OS, their addresses are actually the same!
Thus, a change in the value of ‘x’ will naturally reflect in iRef and vice versa.
Listing 1.16 illustrates this.
/*Beginning of reference01.cpp*/
#include<iostream.h>
void main()
{
int x;
x=10;
cout<<x<<endl;
int & iRef=x; //iRef is a reference to x
iRef=20; //same as x=10;
cout<<x<<endl;
x++; //same as iRef++;
cout<<iRef<<endl;
}
/*End of reference01.cpp*/
Output
10
20
21
Reference variables must be initialized at the time of declaration (otherwise the compiler will
not know what address it has to record for the reference variable).
Reference variables are variables in their own right. They just happen to have the address
of another variable. After their creation, they function just like any other variable.
We have just seen what happens when a value is written into a reference variable. The
value of a reference variable can be read in the same way as the value of an ordinary variable
is read. Listing 1.17 illustrates this.
/*Beginning of reference02.cpp*/
#include<iostream.h>
void main()
{
16 Object-Oriented Programming with C++
int x,y;
x=10;
int & iRef=x;
y=iRef; //same as y=x;
cout<<y<<endl;
y++; //x and iRef unchanged
cout<<x<<endl<<iRef<<endl<<y<<endl;
}
/*End of reference02.cpp*/
Output
10
10
10
11
A reference variable can be a function argument and thus change the value of the parameter
that is passed to it in the function call. Listing 1.18 is an illustrative example.
/*Beginning of reference03.cpp*/
#include<iostream.h>
void increment(int &); //formal argument is a reference
//to the passed parameter
void main()
{
int x;
x=10;
increment(x);
cout<<x<<endl;
}
void increment(int & r)
{
r++; //same as x++;
}
/*End of reference03.cpp*/
Output
11
/*Beginning of reference04.cpp*/
#include<iostream.h>
int & larger(int &, int &);
int main()
{
int x,y;
x=10;
y=20;
int & r=larger(x,y);
r=-1;
cout<<x<<endl<<y<<endl;
}
Introduction to C++ 17
Output
10
–1
In the foregoing listing, ‘a’ and ‘x’ refer to the same memory location while ‘b’ and ‘y’
refer to the same memory location. From the larger() function, a reference to ‘b’, that is,
reference to ‘y’ is returned and stored in a reference variable ‘r’. The larger() function does
not return the value ‘b’ because the return type is int& and not int. Thus, the address of ‘r’
becomes equal to the address of ‘y’. Consequently, any change in the value of ‘r’ also changes
the value of ‘y’. Listing 1.19 can be shortened as illustrated in Listing 1.20.
/*Beginning of reference05.cpp*/
#include<iostream.h>
int & larger(int &, int &);
int main()
{
int x,y;
x=10;
y=20;
larger(x,y)=-1;
cout<<x<<endl<<y<<endl;
}
int & larger(int & a, int & b)
{
if(a>b) //return a reference to the larger parameter
return a;
else
return b;
}
/*End of reference05.cpp*/
Output
10
–1
The name of a non-constant variable can be placed on the left of the assignment operator
because a valid address—the address of the variable—can be determined from it. A call to
a function that returns by reference can be placed on the left of the assignment operator for
the same reason.
If the compiler ¿nds the name of a non-constant variable on the left of the assignment
operator in the source code, it writes instructions in the executable to
x determine the address of the variable,
x transfer control to the byte that has that address, and
18 Object-Oriented Programming with C++
x write the value on the right of the assignment operator into the block that begins with
the byte found above.
A function that returns by reference primarily returns the address of the returned variable.
If the call is found on the left of the assignment operator, the compiler writes necessary
instructions in the executable to
x transfer control to the byte whose address is returned by the function and
x write the value on the right of the assignment operator into the block that begins with
the byte found above.
The name of a variable can be placed on the right of the assignment operator. A call to
a function that returns by reference can be placed on the right of the assignment operator
for the same reason.
If the compiler ¿nds the name of a variable on the right of the assignment operator in the
source code, it writes instructions in the executable to
x determine the address of the variable,
x transfer control to the byte that has that address,
x read the value from the block that begins with the byte found above, and
x push the read value into the stack.
A function that returns by reference primarily returns the address of the returned variable.
If the call is found on the right of the assignment operator, the compiler writes necessary
instructions in the executable to
x transfer control to the byte whose address is returned by the function,
x read the value from the block that begins with the byte found above, and
x push the read value into the stack.
A constant cannot be placed on the left of the assignment operator. This is because
constants do not have a valid address. Moreover, how can a constant be changed? Functions
that return by value, return the value of the returned variable, which is a constant. Therefore,
a call to a function that returns by value cannot be placed on the left of the assignment
operator.
You may notice that the formal arguments of the larger() function in the foregoing listing
have been declared as constant references because they are not supposed to change the values
of the passed parameters even accidentally.
We must avoid returning a reference to a local variable. For example, see Listing 1.21.
/*Beginning of reference06.cpp*/
#include<iostream.h>
int & abc();
void main()
{
abc()=-1;
}
int & abc()
{
int x;
return x; //returning reference of a local variable
}
/*End of reference06.cpp*/
Introduction to C++ 19
The problem with the above program is that when the abc() function terminates, ‘x’ will
go out of scope. Consequently, the statement
abc()=-1;
in the main() function will write ‘–1’ in an unallocated block of memory. This can lead to
run-time errors.
This prototype indicates that the add() function returns a value of integer type and takes two
parameters both of integer type.
Since a function prototype is also a statement, a semicolon must follow it.
Providing names to the formal arguments in function prototypes is optional. Even if
such names are provided, they need not match those provided in the function de¿nition. For
example, see Listing 1.22.
/*Beginning of funcProto.cpp*/
#include<iostream.h>
int add(int,int); //function prototype
void main()
{
int x,y,z;
cout<<“Enter a number: ”;
cin>>x;
cout<<“Enter another number: ”;
cin>>y;
z=add(x,y); //function call
cout<<z<<endl;
}
int add(int a,int b) //function definition
{
return (a+b);
}
/*End of funcProto.cpp*/
Output
Enter a number: 10<enter>
Enter another number: 20<enter>
30
The prototype tells the compiler that the add() function returns an integer-type value. Thus,
the compiler knows how many bytes have to be retrieved from the place where the add()
function is expected to write its return value and how these bytes are to be interpreted.
In the absence of prototypes, the compiler will have to assume the type of the returned
value. Suppose, it assumes that the type of the returned value is an integer. However, the
called function may return a value of an incompatible type (say a structure type). Now,
suppose an integer-type variable is equated to the call to a function where the function call
precedes the function de¿nition. In this situation, the compiler will report an error against
the function de¿nition and not the function call. This is because the function call abided by
its assumption, but the de¿nition did not. However, if the function de¿nition is in a different
¿le to be compiled separately, then no compile-time errors will arise. Instead, wrong results
will arise during run time as Listing 1.23 shows.
/*Beginning of def.c*/
/*function definition*/
struct abc
{
char a;
int b;
float c;
};
struct abc test()
{
struct abc a1;
a1.a=‘x’;
a1.b=10;
a1.c=1.1;
return a1;
}
/*End of def.c*/
/*Beginning of driver.c*/
void main()
{
int x;
x=test(); //no compile time error!!
printf(“%d”,x);
}
/*End of driver.c*/
Output
1688
A compiler that does not enforce prototyping will de¿nitely compile the above program.
But then it will have no way of knowing what type of value the test() function returns.
Introduction to C++ 21
Therefore, erroneous results will be obtained during run time as the output of Listing 1.23
clearly shows.
Since the C++ compiler necessitates function prototyping, it will report an error against
the function call because no prototype has been provided to resolve the function call. Again,
if the correct prototype is provided, the compiler will still report an error since this time the
function call does not match the prototype. The compiler will not be able to convert a struct
abc to an integer. Thus, function prototyping guarantees protection from errors arising out
of incorrect function calls.
What happens if the function prototype and the function call do not match? Such a situation
cannot arise. Both the function prototype and the function de¿nition are created by the same
person, that is, the library programmer. The library programmer puts the function’s prototype in
a header ¿le. He/she provides the function’s de¿nition in a library. The application programmer
includes the header ¿le in his/her application program ¿le in which the function is called. He/
she creates an object ¿le from this application program ¿le and links this object ¿le to the
library to get an executable ¿le.
The function’s prototype also tells the compiler that the add() function accepts two
parameters. If the program fails to provide such parameters, the prototype enables the compiler
to detect the error. A compiler that does not enforce function prototyping will compile a
function call in which an incorrect number and/or type of parameters have been passed. Run-
time errors will arise as in the foregoing case.
Finally, function prototyping produces automatic-type conversion wherever appropriate.
We take the case of compilers that do not enforce prototyping. Suppose, a function expects an
integer-type value (assuming integers occupy four bytes) but a value of double type (assuming
doubles occupy eight bytes) is wrongly passed. During run time, the value in only the ¿rst
four bytes of the passed eight bytes will be extracted. This is obviously undesirable. However,
the C++ compiler automatically converts the double-type value into an integer type. This
is because it inevitably encounters the function prototype before encountering the function
call and therefore knows that the function expects an integer-type value. However, it must
be remembered that such automatic-type conversions due to function prototypes occur only
when it makes sense. For example, the compiler will prevent an attempted conversion from
a structure type to integer type.
Nevertheless, can the same bene¿ts not be realized without prototyping? Is it not possible
for the compiler to simply scan the rest of the source code and ¿nd out how the function has
been de¿ned? There are two reasons why this solution is inappropriate. They are:
x It is inefficient. The compiler will have to suspend the compilation of the line containing
the function call and search the rest of the file.
x Most of the times the function definition is not contained in the file where it is called. It
is usually contained in a library.
Such compile-time checking for prototypes is known as static-type-checking.
will be invoked. For this, function prototypes should be provided to the compiler for matching
the function calls. Accordingly, the linker, during link time, links the function call with the
correct function de¿nition. Listing 1.24 clari¿es this.
/*Beginning of funcOverload.cpp*/
#include<iostream.h>
int add(int,int); //first prototype
int add(int,int,int); //second prototype
void main()
{
int x,y;
x=add(10,20); //matches first prototype
y=add(30,40,50); //matches second prototype
cout<<x<<endl<<y<<endl;
}
int add(int a,int b)
{
return(a+b);
}
int add(int a,int b,int c)
{
return(a+b+c);
}
/*End of funcOverload.cpp*/
Output
30
120
Just like ordinary functions, the de¿nitions of overloaded functions are also put in libraries.
Moreover, the function prototypes are placed in header ¿les.
The two function prototypes at the beginning of the program tell the compiler the two
different ways in which the add() function can be called. When the compiler encounters the
two distinct calls to the add() function, it already has the prototypes to satisfy them both.
Thus, the compilation phase is completed successfully. During linking, the linker ¿nds the
two necessary de¿nitions of the add() function and, hence, links successfully to create the
executable ¿le.
The compiler decides which function is to be called based upon the number, type, and
sequence of parameters that are passed to the function call. When the compiler encounters
the ¿rst function call,
x=add(10,20);
it decides that the function that takes two integers as formal arguments is to be executed.
Accordingly, the linker then searches for the de¿nition of the add() function where there are
two integers as formal arguments.
Similarly, the second call to the add() function
y=add(30,40,50);
/*Beginning of defaultArg.cpp*/
#include<iostream.h>
int add(int,int,int c=0); //third argument has default value
void main()
{
int x,y;
x=add(10,20,30); //default value ignored
y=add(40,50); //default value taken for the
//third parameter
cout<<x<<endl<<y<<endl;
}
int add(int a,int b,int c)
{
return (a+b+c);
}
/*End of defaultArg.cpp*/
Output
60
90
In the above listing, a default value—zero—has been speci¿ed for the third argument of the
add() function. In the absence of a value being passed to it, the compiler assigns the default
value. If a value is passed to it, the compiler assigns the passed value. In the ¿rst call
24 Object-Oriented Programming with C++
x=add(10,20,30);
the values of ‘a’, ‘b’, and ‘c’ are 10, 20, and 30, respectively. But, in the second function call
y=add(40,50);
the values of ‘a’, ‘b’, and ‘c’ are 10, 20, and 0, respectively. The default value—zero—for
the third parameter ‘c’ is taken. This explains the output of the above listing.
Default values can be assigned to more than one argument. Listing 1.26 illustrates this.
/*Beginning of multDefaultArg.cpp*/
#include<iostream.h>
int add(int,int b=0,int c=0); //second and third arguments
//have default values
void main()
{
int x,y,z;
x=add(10,20,30); //all default values ignored
y=add(40,50); //default value taken for the
//third argument
z=add(60); //default value taken for
//the second and the third
//arguments
cout<<x<<endl<<y<<endl<<z<<endl;
}
int add(int a,int b,int c)
{
return (a+b+c);
}
/*End of multDefaultArg.cpp*/
Output
60
90
60
There is no need to provide names to the arguments taking default values in the function
prototypes.
int add(int,int=0,int=0);
Default values must be supplied starting from the rightmost argument. Before supplying
default value to an argument, all arguments to its right must be given default values. Suppose
you write
int add(int,int=0,int);
you are attempting to give a default value to the second argument from the right without
specifying a default value for the argument on its right. The compiler will report an error that
the default value is missing (for the third argument).
Introduction to C++ 25
Default values must be speci¿ed in function prototypes alone. They should not be speci¿ed
in the function de¿nitions.
While compiling a function call, the compiler will de¿nitely have its prototype. Its de¿nition
will probably be located after the function call. It might be in the same ¿le, or it will be in a
different ¿le or library. Thus, to ensure a successful compilation of the function calls where
values for arguments having default values have not been passed, the compiler must be aware
of those default values. Hence, default values must be speci¿ed in the function prototype.
You must also remember that the function prototypes are placed in header ¿les. These are
included in both the library ¿les that contain the function’s de¿nition and the client program
¿les that contain calls to the functions. While compiling the library ¿le that contains the
function de¿nition, the compiler will obviously read the function prototype before it reads
the function de¿nition. Suppose the function de¿nition also contains default values for the
arguments. Even if the same default values are supplied for the same arguments, the compiler
will think that you are trying to supply two different default values for the same argument.
This is obviously unacceptable because the default value can be only one in number. Thus,
default values must be speci¿ed in the function prototypes and should not be speci¿ed again
in the function de¿nitions.
If default values are speci¿ed for the arguments of a function, the function behaves like
an overloaded function and, therefore, should be overloaded with care; otherwise ambiguity
errors might be caused. For example, if you prototype a function as follows:
int add(int,int,int=0);
int add(int,int);
This can confuse the compiler. If only two integers are passed as parameters to the function
call, both these prototypes will match. The compiler will not be able to decide with which
de¿nition the function call has to be resolved. This will lead to an ambiguity error.
Default values can be given to arguments of any data type as follows:
double hra(double,double=0.3);
void print(char=’a’);
x storing the address of the instruction to which the control should jump after the function
terminates.
The C++ inline function provides a solution to this problem. An inline function is a function
whose compiled code is ‘in line’ with the rest of the program. That is, the compiler replaces
the function call with the corresponding function code. With inline code, the program does
not have to jump to another location to execute the code and then jump back. Inline functions,
thus, run a little faster than regular functions.
However, there is a trade-off between memory and speed. If an inline function is
called repeatedly, then multiple copies of the function definition appear in the code
(see Figures 1.1 and 1.2). Thus, the executable program itself becomes so large that it occupies
a lot of space in the computer’s memory during run time. Consequently, the program runs
slow instead of running fast. Thus, inline functions must be chosen with care.
For specifying an inline function, you must:
x prefix the definition of the function with the inline keyword and
x define the function before all functions that call it, that is, define it in the header file
itself.
The following listing illustrates the inline technique with the inline cube() function that
cubes its argument. Note that the entire de¿nition is in one line. That is not a necessary
condition. But if the de¿nition of a function does not ¿t in one line, the function is probably
a poor candidate for an inlne function!
/*Beginning of inline.cpp*/
#include<iostream.h>
inline double cube(double x) { return x*x*x; }
void main()
{
double a,b;
double c=13.0;
a=cube(5.0);
b=cube(4.5+7.5);
cout<<a<<endl;
cout<<b<<endl;
cout<<cube(c++)<<endl;
cout<<c<<endl;
}
/*End of inline.cpp*/
28 Object-Oriented Programming with C++
Output
125
1728
2197
14
However, under some circumstances, the compiler, despite your indications, may not expand the
function inline. Instead, it will issue a warning that the function could not be expanded inline
and then compile all calls to such functions in the ordinary fashion. Those conditions are:
x The function is recursive.
x There are looping constructs in the function.
x There are static variables in the function.
Let us brieÀy compare macros in C and inline function in C++. Macros are a poor predecessor
to inline functions. For example, a macro for cubing a number is as follows:
#define CUBE(X) X*X*X
Here, a mere text substitution takes place with‘X’ being replaced by the macro parameter.
a=CUBE(5.0); //replaced by a=5.0*5.0*5.0;
b=CUBE(4.5+7.5); //replaced by
//b=4.5+7.5*4.5+7.5*4.5+7.5;
c=CUBE(x++); //replaced by c=x++*x++*x++;
Only the ¿rst statement works properly. An intelligent use of parentheses improves matters
slightly.
#define CUBE(X) ((X)*(X)*(X))
Even now, CUBE(c++) undesirably increments ‘c’ thrice. But the inline cube() function
evaluates ‘c’, passes the value to be cubed, and then correctly increments ‘c’ once.
It is advisable to use inline functions instead of macros.
Summary
Variables sometimes inÀuence each other’s values. be safe from unintentional modi¿cation by functions
A change in the value of one may necessitate a other than those de¿ned by him/her. Moreover, they do
corresponding adjustment in the value of another. It not guarantee a proper initialization of data members
is, therefore, necessary to pass these variables together of structure variables.
in a single group to functions. Structures enable us to Both of the above drawbacks are in direct
do this. contradiction with the characteristics possessed by
Structures are used to create new data types. This real-world objects. A real-world object has not only
is a two-step process. a perfect interface to manipulate its internal parts but
Step 1: Create the structure itself. also exclusive rights to do so. Consequently, a real-
world object never reaches an invalid state during its
Step 2: Create associated functions that work upon
lifetime. When we start operating a real-world object, it
variables of the structure.
automatically assumes a valid state. In object-oriented
While structures do fulfil the important need
programming systems (OOPS), we can incorporate
described above, they nevertheless have limitations.
these features of real-world objects into structure
They do not enable the library programmer to make
variables.
variables of the structure that he/she has designed to
Introduction to C++ 29
Inheritance allows a structure to inherit both data of the variable with which it is sharing memory. Calls
and functions of an existing structure. Polymorphism to functions that return by reference can be placed on
allows different functions to have the same name. It is the left of the assignment operator.
of two types: static and dynamic. Function prototyping is necessary in C++. Functions
Console output is achieved in C++ with the help can be overloaded. Functions with different signatures
of insertion operator and the cout object. Console can have the same name. A function argument can be
input is achieved in C++ with the help of extraction given a default value so that if no value is passed for it
operator and the cin object. in the function call, the default value is assigned to it.
In C++, variables can be de¿ned anywhere in a If a function is declared inline, its de¿nition replaces
function. A reference variable shares the same memory its call, thus, speeding up the execution of the resultant
location as the one of which it is a reference. Therefore, executable.
any change in its value automatically changes the value
Key Terms
creating new data types using structures - cin
lack of data security in structures - istream_withassign class
no guaranteed initialization of data in structures - extraction operator
procedure-oriented programming system - iostream.h header ¿le
object-oriented programming system - endl
data security in classes reference variable
guaranteed initialization of data in classes - passing by reference
inheritance - returning by reference
polymorphism importance of function prototyping
console input/output in C++ function overloading
- cout default values for function arguments
- ostream_withassign class inline functions
- insertion operator
Exercises
1. Which programming needs do structures ful¿ll? Why 10. State true or false.
does C language enable us to create structures? (a) Structures enable a programmer to secure the
2. What are the limitations of structures? data contained in structure variables from being
3. What is the procedure-oriented programming changed by unauthorized functions.
system? (b) The insertion operator is used for outputting
4. What is the object-oriented programming system? in C++.
5. Which class is ‘cout’ an object of? (c) The extraction operator is used for outputting
6. Which class is ‘cin’ an object of? in C++.
7. What bene¿ts does a programmer get if the compiler (d) A call to a function that returns by reference
forces him/her to prototype a function? cannot be placed on the left of the assignment
8. Why will an ambiguity error arise if a default value operator.
is given to an argument of an overloaded function? (e) An inline function cannot have a looping
9. Why should default values be given to function construct.
arguments in the function’s prototype and not in the 11. Think of some examples from your own experience in
function’s de¿nition? C programming where you felt the need for structures.
30 Object-Oriented Programming with C++
Do you see an opportunity for programming in OOPS on the left-hand side of the assignment operator.
in those examples? Experiment and ¿nd out whether such calls can be
12. Structures in C do not enable the library programmers chained. Consider the following:
to guarantee an initialization of data. Appreciate the
f(a, b) = g(c, d) = x;
implications of this limitation by taking the date
structure as an example. where ‘f’ and ‘g’ are functions that return by reference
13. Calls to functions that return by reference can be put while ‘a’, ‘b’, ‘c’, ‘d’, and ‘x’ are variables.
2 Classes and Objects
The previous chapter refreshed the reader’s knowledge of the structure construct provided
by C language—its use and usage. It also dealt with a critical analysis of structures along with
their pitfalls and limitations. The reader was made aware of a strong need for data security and
for a guaranteed initialization of data that structures do not provide.
This chapter is a logical continuation to the previous one. It begins with a thorough
explanation of the class construct of C++ and the ways by which it ful¿ls the above-mentioned
O needs. Superiority of the class construct of C++ over the structure construct of C language is
emphasized in this chapter.
V This chapter also deals with how classes enable the library programmer to provide exclusive
E rights to the associated functions.
A description of various types and features of member functions and member data ¿nds a
R prominent place in this chapter. This description covers:
x Overloaded member functions
V
x Default values for the arguments of member functions
I x Inline member functions
x Constant member functions
E x Mutable data members
W x Friend functions and friend classes
x Static members
A section in this chapter is devoted to namespaces. They enable the C++ programmer to
prevent pollution of the global namespace that leads to name clashes.
Example code to tackle arrays of objects and arrays inside objects form the penultimate
portion of this chapter.
The chapter ends with an essay on nested classes—their need and use.
The bug arising out of the last line of the main() function above is easily detected even
by a visual inspection. Nevertheless, the same will certainly not be the case if the code is
around 25,000 lines long. Lines similar to the last line of the main() function above may be
scattered all over the code. Thus, they will be dif¿cult to hunt down.
Notice that the absence of a facility to bind the data and the code that can have the exclusive
rights to manipulate the data can lead to dif¿cult-to-detect run-time bugs. C does not provide
the library programmer with the facilities to encapsulate data, to hide data, and to abstract
data.
The C++ compiler provides a solution to this problem. Structures (the struct keyword)
have been rede¿ned to allow member functions also. Listing 2.2 illustrates this.
/*Beginning of structDistance01.cpp*/
#include<iostream.h>
struct Distance
{
int iFeet;
float fInches;
void setFeet(int x)
{
iFeet=x;
}
int getFeet()
{
return iFeet;
}
void setInches(float y)
{
fInches=y;
}
float getInches()
{
return fInches;
}
};
void main()
{
Distance d1,d2;
d1.setFeet(2);
d1.setInches(2.2);
d2.setFeet(3);
d2.setInches(3.3);
cout<<d1.getFeet()<<“ ”<<d1.getInches()<<endl;
cout<<d2.getFeet()<<“ ”<<d2.getInches()<<endl;
Classes and Objects 33
}
/*End of structDistance01.cpp*/
Output
2 2.2
3 3.3
First, we must notice that functions have also been de¿ned within the scope of the structure
de¿nition. This means that not only the member data of the structure can be accessed through
the variables of the structures but also the member functions can be invoked. The struct
keyword has actually been rede¿ned in C++. This latter point is illustrated by the main()
function in Listing 2.2 above. We must make careful note of the way variables of the structure
have been declared and how the member functions have been invoked.
Member functions are invoked in much the same way as member data are accessed, that is,
by using the variable-to-member access operator. In a member function, one can refer directly
to members of the object for which the member function is invoked. For example, as a result
of the second line of the main() function in Listing 2.2, it is d1.iFeet that gets the value of
2. On the other hand, it is d2.iFeet that gets the value of 3 when the fourth line is invoked.
This is explained in the section on the this pointer that follows shortly.
Each structure variable contains a separate copy of the member data within itself. However,
only one copy of the member function exists. Again, the section on the this pointer explains
this.
However, in the above example, note that the member data of structure variables can still
be accessed directly. The following line of code illustrates this.
d1.iFeet=2; //legal!!
What is the advantage of having member functions also in structures? We have put together
the data and functions that work upon the data but we have not been able to give exclusive
rights to these functions to work upon the data. Problems in code debugging can still arise
as before. Specifying member functions as public but member data as private obtains the
advantage. The syntax for this is illustrated by Listing 2.3.
/*Beginning of structDistance02.cpp*/
#include<iostream.h>
struct Distance
{
private:
int iFeet;
float fInches;
public:
void setFeet(int x)
{
iFeet=x; //LEGAL: private member accessed by
//member function
}
int getFeet()
34 Object-Oriented Programming with C++
{
return iFeet;
}
void setInches(float y)
{
fInches=y;
}
float getInches()
{
return fInches;
}
};
void main()
{
Distance d1,d2;
d1.setFeet(2);
d1.setInches(2.2);
d2.setFeet(3);
d2.setInches(3.3);
d1.iFeet++; //ERROR!!: private member accessed by
//non-member function
cout<<d1.getFeet()<<“ ”<<d1.getInches()<<endl;
cout<<d2.getFeet()<<“ ”<<d2.getInches()<<endl;
}
/*End of structDistance02.cpp*/
First, let us have a close look at the modi¿ed de¿nition of the structure Distance. Two
new keywords, private and public have been introduced in the de¿nition of the structure. Their
presence in the foregoing example tells the compiler that iFeet and fInches are private data
members of variables of the structure Distance and the member functions are public. Thus,
values of iFeet and fInches of each variable of the structure Distance can be accessed/
modi¿ed only through member functions of the structure and not by any non-member
function in the program (again note that it is the iFeet and fInches of the invoking object
that are accessed/modi¿ed by the member functions). Any attempt to violate this restriction
is prevented by the compiler because that is how the C++ compiler recognizes the private
keyword. Since the member functions are public, they can be invoked from any part of the
program.
As we can observe from Listing 2.3, the compiler refuses to compile the line in which a
private member of a structure variable is accessed from a non-member function (the main()
function in Listing 2.3).
The keywords private and public are also known as access modi¿ers or access speci¿ers
because they control the access to the members of structures.
C++ introduces a new keyword class as a substitute for the keyword struct. In a structure,
members are public by default. See the de¿nition in Listing 2.4.
struct Distance
{
private:
int iFeet;
float fInches;
Classes and Objects 35
public:
void setFeet(int x)
{
iFeet=x;
}
int getFeet()
{
return iFeet;
}
void setInches(float y)
{
fInches=y;
}
float getInches()
{
return fInches;
}
};
In Listing 2.4, the member functions have not been placed under any access modi¿er.
Therefore, they are public members by default.
On the other hand, class members are private by default. This is the only difference between
the class keyword and the struct keyword.
Thus, the structure Distance can be rede¿ned by using the class keyword as shown in
Listing 2.5.
class Distance
{
int iFeet; //private by default
float fInches; //private by default
36 Object-Oriented Programming with C++
public:
void setFeet(int x)
{
iFeet=x;
}
int getFeet()
{
return iFeet;
}
void setInches(float y)
{
fInches=y;
}
float getInches()
{
return fInches;
}
};
The struct keyword has been retained to maintain backward compatibility with C
language. A header ¿le created in C might contain the de¿nition of a structure, and structures
in C will have member data only. A C++ compiler will easily compile a source code that has
included the above header ¿le since the new de¿nition of the struct keyword allows, not
mandates, the inclusion of member functions in structures.
Functions in a C language source code access member data of structures. A C++ compiler
will easily compile such a source code since the C++ compiler treats members of structures
as public members by default.
2.1.2 Objects
Variables of classes are known as objects.
An object of a class occupies the same amount of memory as a variable of a structure that
has the same data members. This is illustrated by Listing 2.6.
Listing 2.6 Size of a class object is equal to that of a structure variable with identical
data members
/*Beginning of objectSize.cpp*/
#include<iostream.h>
struct A
{
char a;
int b;
float c;
};
class B //a class with the same data members
{
char a;
int b;
float c;
};
void main()
{
Random documents with unrelated
content Scribd suggests to you:
recognize in the young priest I seemed to be the Tuptim he had
known in his boyhood, and who had once been his betrothed wife."
At this part of Tuptim's recital, the women held up their hands in
profound astonishment, and the men judges grinned maliciously,
displaying their hateful gums, red with the juice of the betel-nut.
The poor girl's pale lips quivered, and her whole face testified to the
immensity of her woe, as with simple, truthful earnestness she
asseverated: "P'hra Bâlât, whom you have condemned to torture and
to death, has not sinned. He is innocent. The sin is mine, and mine
only. I knew that I was a woman, but he did not. If I had known all
that he has taught me since I became his disciple, I could not have
committed the great sin of which I am accused. I would have tried,
indeed and truly, I would have tried to endure my life in the palace,
and would not have run away. O lady dear! believe that I am
speaking the truth. I grew quiet and happy because I was near him,
and he taught me every day, and I can say the whole of the Nava
d'harma (Divine Law) by heart. You can ask his other disciples who
were with me, and they will tell you that I was always modest and
humble, and we all lay at his feet by night. Indeed, dear lady, I did
not so much want to be his wife after he became a p'hra (priest),
but only to be near him. On Sunday morning, those men," pointing
to the two priests who sat apart, "came to the cell to see P'hra Bâlât,
and it so happened that I had overslept myself. I had just got up
and was arranging my dress, thinking that I was alone in the cell,
when I heard a low chuckling laugh. In an instant I turned and faced
them, and felt that I was degraded forever.
"Believe me, dear lady," continued Tuptim, growing more and more
eloquent as she became still more earnest in her recital. "I was
guilty, it is true, when I fled from my gracious master, the king, but I
never even contemplated the sin of which I am accused by those
men. I knew that I was innocent, and I begged them to let me leave
the temple, and hide myself anywhere, telling them that P'hra Bâlât
did not know who I was, or that I was a woman; but they only
laughed and jeered at me. I fell on my knees at their feet, and
implored them, entreated them in the name of all that is holy and
sacred, to keep my secret and let me go; but they only laughed and
jeered at me the more; they would not be merciful,"—here the poor
girl gasped as if for breath, while two large tears coursed down her
cheeks,—"and then I defied them, and I still defy them," she added,
shaking her manacled hands at them.
The two priests looked at the girl unmoved, chewing their betel all
the while; the judges listened in silence, with an air of amused
incredulity, as to a fairy-tale. She continued:—
"Just then P'hra Bâlât and his other disciples returned from their
morning ablutions. I crawled to his feet, and told him that I was
Tuptim. He started back and recoiled to the end of the cell, as if the
very earth had quaked beneath him, leaving me prostrate and
overwhelmed with horror at what I had done. In a moment
afterwards he came back to me, and, while weeping bitterly himself,
begged me that I would cry no more. But the sight of his tears, and
the grief in my heart, made me feel as if I were being swallowed up
in a great black abyss, and I could not help crying more and more.
Then he tried to soothe me, and said, 'Alas! Tuptim, thou hast
committed a great sin. But fear not. We are innocent; and for the
sake of the great love thou hast shown to me, I am ready to suffer
even unto death for thee.' This is the whole truth. Indeed, indeed, it
is!"
"Well, well!" said P'hayaprome Baree Rak, "you have told your story
beautifully, but nobody believes you. How will you tell us who
shaved off your hair and your eyebrows, and brought you that
priest's dress you had on yesterday?"
The simple grandeur of that fragile child, as she folded her chained
hands across her bosom, as if to still its tumultuous heaving, and
replied, "I will not!" defies all description.
I had drawn quite near to Tuptim when she began her simple
narrative, and was so much absorbed in attention to what she said,
and in admiration of the fearlessness as well as of the beauty and
majesty of that little figure, that I had remained rooted to the spot,
standing there mechanically, and hardly noting what was going on
around me. But the effect of that reply was startling; it brought me
suddenly to my senses and to a full appreciation of the scene before
me.
There was a child of barely sixteen years hurling defiance, at her
own risk and peril, at the judges who appeared as giants beside her.
To make such a reply to those executors of Siam's cruel laws was
not only to accept death, but all the agonies of merciless torture. As
her refusal fell like a thunderbolt upon my startled ears, she seemed
a very Titan among the giants.
"Strip her, and give her thirty blows," shouted the infuriated
P'hayaprome Baree Rak, in a voice hoarse with passion; and Khoon
Thow App looked calmly on.
Presently the crowd opened, and a litter borne by two men was
brought into the hall. On it lay the mutilated form of the priest Bâlât,
who had just undergone the torture, in order to make him confess
his guilt and that of his accomplice, Tuptim; but as the minutes of
the ecclesiastical court stated, "it had not been possible to elicit from
him even an indication that he had anything to confess." His priestly
robes had been taken from him, and he was dressed like any
ordinary layman, except that his hair and eyebrows were closely
shaven. They laid him down beside Tuptim, hoping that the sight of
her under torture would induce him to confess.
A SIAMESE SLAVE-GIRL.
The next moment Tuptim was stripped of her vest and bound to a
stake, and the executioners proceeded to obey the orders of the
judge. When the first blow descended on the girl's bare and delicate
shoulders, I felt as if bound and lacerated myself, and losing all
control over my actions, forgetting that I was a stranger and a
foreigner there, and as powerless as the weakest of the oppressed
around me, I sprang forward, and heard my voice commanding the
executioners to desist, as they valued their lives.
The Amazons at once dropped their uplifted bamboos, and "Why
so?" asked the judge. "At least till I can plead for Tuptim before his
Majesty," I replied. "So be it," said the wretch; "go your way; we will
wait your return."[5] Tuptim was unbound, and the moment she was
released she crouched down and concealed herself under the folds
of the canvas litter in which the priest lay motionless and silent.
I forced my way through the curious crowd, who stood on tiptoe and
with necks outstretched, trying to get a sight of the guilty pair. On
leaving the hall, I met the slave-girl Phim, who followed me into the
palace, wringing her hands and sobbing bitterly. The king was in his
breakfast-hall, and the smell of food made me feel sick and dizzy as
I climbed the lofty staircase, for I had eaten nothing that day.
Nevertheless, I walked as rapidly as possible up to the chair in which
the king was seated, fearing that I might lose my courage if I
deliberated a moment. "Your Majesty," I began to say, in a voice that
seemed quite strange to me, "I beg, I entreat your pity on poor
Tuptim. I assure you that she is innocent. If you had known from the
beginning that she was betrothed to another man, you would never
have taken her to be your wife. She is not guilty; and the priest, too,
is innocent. Oh! do be gracious to them and forgive them both! I
pray your Majesty to give me a scrap of writing to say that she is
forgiven, and that the priest, too, is pardoned, through your
goodness; only let me—" My voice failed me, and I sank upon the
floor by the king's chair. "I beg your Majesty's pardon—" "You are
mad," said the monarch; and, fixing a cold stare upon me, he burst
out laughing in my face. I started to my feet as if I had received a
blow. Staggering to a pillar, and leaning against it, I stood looking at
him. I saw that there was something indescribably revolting about
him, something fiendish in his character which had never struck me
before, and I was seized with an inexpressible horror of the man.
Stupefied and amazed quite as much at finding myself there as at
the new development I witnessed, thought and speech alike failed
me, and I turned to go away.
"Madam," said that man to me, "come back. I have granted your
petition, and the woman will be condemned to work in the rice-mill.
You need not return to the court-house. You had better go to the
school now."
I could not thank him; the revulsion of feeling was too great. I
understood him perfectly, but I had no power to speak. I went away
without a word, and at the head of the stairs met one of the women
judges bringing some papers in her hand to the king. Instead of
going to the school I went home, utterly sick and prostrated.
FOOTNOTES:
[4] "The English Governess at the Siamese Court," p. 95.
[5] I cannot account for the regard paid to my words on this and
other occasions by the officers of the court, except from the fact
of the general belief that I had great influence with the king, and
the supposition entertained by many that I was a member of the
Secret Council, which is, in reality, the supreme power in Siam.
CHAPTER IV.
THE KING CHANGES HIS MIND.
About two o'clock that very afternoon I was startled to see two
scaffolds set up on the great common in front of my windows,
opposite the palace. A vast crowd of men, women, and children had
already collected from every quarter, in order to see the spectacle,
whatever it might happen to be. A number of workmen were driving
stakes and bringing up strange machines, under the hurried
instructions of several high Siamese officials. There was an
appearance of great and general excitement among the crowd on
the green, and I became sufficiently aroused to inquire of my maid
what was the reason of all this preparation and commotion. She
informed me that a Bâdachit (guilty priest) and a Nangharm (royal
concubine) were to be exposed and tortured for the improvement of
the public morals that afternoon. It was afternoon already.
As I afterwards learned, I had no sooner left the king than the
woman judge I had met at the head of the staircase laid before him
the proceedings of both the trials, of Bâlât and Tuptim. On reading
them he repented of his promised mercy, flew into a violent rage
against Tuptim and me, and, not knowing how to punish me except
by showing me his absolute power of life and death over his
subjects, ordered the scaffolds to be set up before my windows, and
swore vengeance against any person who should again dare to
oppose his royal will and pleasure. To do justice to the king, I must
here add that, having been educated a priest, he had been taught to
regard the crime of which Tuptim and Bâlât were accused as the
most deadly sin that could be committed by man.
The scaffolds or pillories on which the priest and Tuptim were to be
exposed were made of poles, and about five feet high; and to each
were attached two long levers, which were fastened to the neck of
the victim, and prevented his falling off, while they were so arranged
as to strangle him in case this was the sentence.
All the windows of the long antechamber that filled the eastern front
of the palace were thrown open, and I could see the hurried
preparations making for the king, the princes and princesses, and all
the great ladies of the court, who from there were to witness the
exquisite torture that awaited the hapless Tuptim.
Paralyzed by the knowledge that the only person who could have
done anything to mitigate the barbarous cruelty that was about to
be perpetrated—her Britannic Majesty's Consul, T.G. Knox, now
Consul-General—was then absent from Bangkok, I looked in helpless
despair at what was going on before me. I longed to escape into the
forest, or to take refuge with the missionaries, who lived several
miles down the river; but so dense was the crowd and so horrible
the idea of deserting poor Tuptim and leaving her to suffer alone,
that I felt obliged to stay and sympathize with her and pray for her,
at the least. I thus compelled myself to endure what was one of the
severest trials of my life.
A little before three o'clock the instruments of torture were brought,
and placed beside the scaffolds. Soon a long, loud flourish of
trumpets announced the arrival of the royal party, and the king and
all his court were visible at the open windows; the Amazons, dressed
in scarlet and gold, took their post in the turrets to guard the
favored fair ones who were doomed to be present and to witness
the sufferings of their former companion.
Suddenly the throng sent up a thrilling cry, whether of joy or sorrow
I could not comprehend, and, the moment after, the priest was
hoisted upon the scaffold to the right, while Tuptim tranquilly
ascended that to the left, nearest my windows. I thought I could see
that the poor priest turned his eyes, full of love and grief, towards
her.
I need not attempt to depict the feelings with which I saw the little
lady, with her hands, which were no longer chained, folded upon her
bosom, look calmly down upon the heartless and abandoned rabble
who, as usual, flocked around the scaffold to gloat upon the
spectacle, and who usually greet with ferocious howls the agonies of
the poor tortured victims. But, on this occasion, the rabble were
awed into silence; while some simple hearts, here and there, firm
believers in Tuptim's innocence, were so impressed by her calm self-
possession, that they even prostrated themselves in worship of that
childish form.
My windows were closed upon the scene; but that tiny figure, with
her scarlet scarf fluttering in the breeze, had so strong a fascination
for me, that I could not withdraw, but leaned against the shutters,
an unwilling witness of what took place, with feelings of pain,
indignation, pity, and conscious helplessness which can be imagined.
Two trumpeters, one on the right and one on the left, blared forth
the nature of the crime of which the helpless pair were accused. Ten
thousand eyes were fixed upon them, but no sound, no cry, was
heard. Every one held his breath, and remained mute in fixed
attention, in order not to lose a single word of the sentence that was
to follow. Again the trumpets sounded, and the conviction of the
accused, with the judgment that had been passed upon them, was
announced. Then the spell was broken, and some of the throng, as
if desirous to propitiate the royal spectator at the window, made the
air ring with their shouts; while others, going still further, showered
all manner of abuse upon the poor girl, as she stood calmly awaiting
her fate upon those shaking wooden posts.
Nothing could surpass the dignity of demeanor with which the little
lady sustained the storm of calumny from the more mercenary of
the rabble around her; but the rapidity with which the color came
and went in her cheeks, which were now of glowing crimson and
now deadly pale, and the astonishment and indignation which
flashed from her eyes, showed the agitation within.
The shrill native trumpets sounded for the third time. The multitude
was again hushed into a profound silence, and the executioners
mounted a raised platform to apply the torture to Tuptim. For one
moment it seemed as if the intense agony exceeded her power of
endurance. She half turned her back upon the royal spectator at the
window, her form became convulsed, and she tried to hide her face
in her hands. But she immediately raised herself up as by a supreme
effort, and her voice rang out, like a clear, deep-toned silver bell:
"Chân my di phit; Khoon P'hra Bâlât ko my me phit; P'hra Buddh the
Chow sap möt." She had hardly done speaking when she uttered an
agonized cry, wild and piercing. It was peculiarly touching; the cry
was that of a child, an infant falling from its mother's arms, and she
fell forward insensible upon the two poles placed there to support
her.
The attendant physicians soon restored her to consciousness, and,
after a short interval, the torture was again applied. Once more her
voice rang out more musical still, for its quivering vibrations were full
of the tenderest devotion, the most sublime heroism: "I have not
sinned, nor has the priest my lord Bâlât sinned. The sacred Buddh[6]
in heaven knows all." Every torture that would agonize, but not kill,
was employed to wring a confession of guilt from the suffering
Tuptim; but every torture, every pang, every agony, failed, utterly
and completely failed, to bring forth anything but the childlike
innocence of that incomparable pagan woman. The honor of the
priest Bâlât seemed inexpressibly more precious to her than her own
life, for the last words I heard from her were: "All the guilt was
mine. I knew that I was a woman, but he did not."
After this I neither heard nor saw anything more. I was completely
exhausted and worn out, and had no strength left to endure further
sight of this monstrous, this inhuman tragedy. Kind nature came to
my relief, and I fainted.
When I again looked from my window the scaffolds were removed,
the crowd had departed, the sun had set. I strained my eyes, trying
if I could distinguish anything on the great common before the
house. There was a thick mist loaded with sepulchral vapors, a
terrifying silence, an absolute quiet that made me shudder, as if I
were entombed alive. At last I saw one solitary person coming
towards my house through the gathering darkness. It was the slave-
girl, Phim, whose life had been saved by the resolute bravery of her
mistress; for it was she who had bought the priest's dress and aided
her mistress to escape from the palace. She came to me in secret to
tell me that the most merciful and yet the most dreadful doom,
death by fire,—which is the punishment assigned by the laws of
Siam to the crime of which they were accused,—had been
pronounced upon the priest and Tuptim by that most irresponsible of
human beings, the King of Siam; that they had suffered publicly
outside of the moat and wall which enclose the cemetery Watt Sah
Katè; and that some of the common people had been terribly
affected by the sight of the priest's invincible courage and of
Tuptim's heroic fortitude. With her low, massive brow, her wild,
glistening eyes, and her whole soul in her face, she spoke as if she
still beheld that fragile form in its last struggle with the flaming fire
that wrapped it round about, and still heard her beloved mistress's
voice, as she confronted the populace, holding up her mutilated
hands, and saying: "I am pure, and the priest, my lord Bâlât, is pure
also. See, these fingers have not made my lips to lie. The sacred
Buddh in heaven judge between me and my accusers!"
The slave-girl's grief was as deep and lasting as her gratitude. Every
seventh day she offered fresh flowers and odoriferous tapers upon
the spot where her mistress and the priest had suffered, firmly
believing that their disembodied souls still hovered about the place
at twilight, bewailing their cruel fate. She assured me that she often
heard voices moaning plaintively through the mellow evening air,
growing deeper and gathering strength as she listened, and seeming
to draw her very soul away with them; now tenderly weeping, now
fervently exulting, until they became indistinct, and finally died away
in the regions of the blessed and the pure.
I afterwards learned that the fickle populace, convinced of the
innocence of Bâlât and Tuptim, would have taken speedy vengeance
on the two priests, their accusers, had they not escaped from
Bangkok to a monastery at Paknâm; and that the twenty caties
offered for the capture of Tuptim had been expended in the
purchase of yellow robes, earthen pots, pillows, and mats for the
use of the bonzes at Watt Rajah Bah ditt Sang, no priest being
allowed to touch silver or gold.
The name Bâlât, which signifies "wonderful," had been given to the
priest by the high-priest, Chow Khoon Sah, because of his deep piety
and his intuitive perception of divine and holy truths. The name
which his mother bestowed upon him, and by which Tuptim had
known him in her earlier years, was Dang, because of his
complexion, which was a golden yellow. On being bereft of Tuptim,
to whom he was tenderly attached, he entered the monastery, and
became a priest, in order that, by austere devotion and the study of
the Divine Law, he might wean his heart from her and distract his
mind from the contemplation of his irreparable loss.
For more than a month after Tuptim's sad death I did not see the
king. At last he summoned me to his presence, and never did I feel
so cold, so hard, and so unforgiving, as when I once more entered
his breakfast-hall. He took no notice of my manner, but, as soon as
he saw me, began with what was uppermost in his mind. "I have
much sorrow for Tuptim," he said; "I shall now believe she is
innocent. I have had a dream, and I had clear observation in my
vision of Tuptim and Bâlât floating together in a great wide space,
and she has bent down and touched me on the shoulder, and said to
me, 'We are guiltless. We were ever pure and guiltless on earth, and
look, we are happy now.' After discoursing thus, she has mounted
on high and vanished from my further observation. I have much
sorrow, mam, much sorrow, and respect for your judgment; but our
laws are severe for such the crime. But now I shall cause monument
to be erected to the memory of Bâlât and Tuptim."
Any one who may now pass by Watt Sah Katè will see two tall and
slender P'hra Chadees, or obelisks, erected by order of the king on
the spot where those lovely Buddhists suffered, each bearing this
inscription: "Suns may set and rise again, but the pure and brave
Bâlât and Tuptim will never more return to this earth."
FOOTNOTES:
[6] The Siamese in their prayers and invocations abbreviate the
titles of the Buddha; the more educated using the word "Buddh,"
and the common people "P'huth."
CHAPTER V.
SLAVERY IN THE GRAND ROYAL PALACE OF THE "INVINCIBLE AND
BEAUTIFUL ARCHANGEL."[7]
One morning in the early part of May, 1863, I went at the usual hour
to my temple school-room, and found that all my pupils had gone to
the Maha P'hra Sâât to attend a religious ceremony, at which I also
was requested to be present.
Following the directions of one of the flower-girls, I turned into a
long, dark alley, through which I hurried, passing into another, and
keeping, as I thought, in the right direction. These alleys brought me
at last into one of those gloomy walled streets, into which no
sunlight ever penetrated, and which are to be found only in
Bangkok, the farther end of which seemed lost in mist and darkness.
Stone benches, black with moss and fungi, lined it at intervals, and a
sort of pale night-grass covered the pathway. There was not a soul
to be seen throughout its whole length, which appeared very
natural, for it did not seem as if the street were made for any one to
walk in, but as if it were intended to be kept secluded from public
use. I walked on, however, looking for some opening out of it, and
hoping every moment to find an exit. But I suddenly came to the
end. It was a cul-de-sac, and a high brick wall barred my further
progress.
In the middle of this wall was set a door of polished brass. The
shadow of a tall and grotesque façade rested upon the wall and on
the narrow deserted street, like an immense black pall. The solitude
of the place was strangely calm. With that frightful din and roar of
the palace life so near, the silence seemed almost supernatural. It
cast a shadow of distrust over me. I almost felt as if that wall, that
roof with its towering front, were built of the deaf stones spoken of
in Scripture. All at once the wind rattled the dry grass on the top of
the wall, making a low, soft, mournful noise. I started from my
revery, hardly able to account for the feeling of dread that crept over
me. Half ashamed of my idle fears, I pushed at the door with all my
might. Slowly, noiselessly, the huge door swung back, and I stepped
into a paved court-yard, with a garden on one side and a building
suggestive of nocturnal mystery and gloom on the other.
The façade of this building was still more gloomy than that on the
outside of the wall. All the windows were closed. On the upper story
the shutters were like those used in prisons. No other house could
be seen. The high wall ran all round and enclosed the garden. The
walks were bordered with diminutive Chinese trees, planted in
straight rows; grass covered half of them, and moss the rest.
Nothing could be imagined more wild and more deserted than this
house and this garden. But the object that attracted my immediate
attention was a woman, the only animate being then visible to me in
the apparent solitude. She was seated beside a small pond of water,
and I soon discovered that she was not alone, but was nursing a
naked child about four years old.
The moment the woman became conscious of my presence, she
raised her head with a quick, impetuous movement, clasped her
bare arms around the nude form at her breast, and stared at me
with fixed and defiant eyes. Her aspect was almost terrifying. She
seemed as if hewn out of stone and set there to intimidate intruders.
She was large, well made, and swarthy; her features were gaunt and
fierce, but looked as if her face might once have been attractive. I
relaxed my hold of the door; it swung back with a dull, ominous
thud, and I stood half trembling beside the dark, defiant woman,
whose eyes only gave any indication of vitality, hoping to prevail
upon her to show me my way out of that dismal solitude.
The moment I approached her, however, I was seized with
inexpressible dismay; pity and astonishment, mingling with a sense
of supreme indignation, held me speechless for a time. She was
naked to the waist, and chained,—chained like a wild beast by one
leg to a post driven into the ground, and without the least shelter
under that burning sky.
The chain was of cast-iron, and heavy, consisting of seven long
double-links, attached to a ring, and fitted close to the right leg just
above the ankle; it was secured to the post by a rivet. Under her lay
a tattered fragment of matting, farther on a block of wood for a
pillow, and on the other side were several broken Chinese umbrellas.
Growing more and more bewildered, I sat down and looked at the
woman in a sort of helpless despair. The whole scene was startlingly
impressive; the apathy, the deadness, and the barbarous cruelty of
the palace life, were never more strikingly brought before me face to
face. Here there was no doubting, no denying, no questioning the
fact that this unhappy creature was suffering under some cruel
wrong, which no one cared to redress. Naked to the waist, her long
filthy hair bound in dense masses around her brow, she sat calmly,
uncomplainingly, under a burning tropical sun, such as we children
of a more temperate clime can hardly imagine, fierce, lurid, and
scorching, nursing at her breast a child full of health and begrimed
with dirt, with a tenderness that would have graced the most high-
born gentlewoman.
I remained long and indignantly silent, before I could find voice for
the questions that rose to my lips. But at length I inquired her name.
"Pye-sia" (begone), was her fierce reply.
"Why art thou thus chained? Wilt thou not tell me?" I pleaded.
"Pye" (go), said the woman, snatching her breast impatiently from
the sucking child, and at the same time turning her back upon me.
The child set up a tremendous scream, which was re-echoed
through the strange place. The woman turned and took him into her
arms; and as if there were an indwelling persuasiveness about them,
he was quieted in an instant.
Rocking him to and fro, with her face resting against his unwashed
cheek, she was no longer repulsive, but glorious, clothed in the
beauty and strength of a noble human love. I rose respectfully from
the low wall of the pond, where I had seated myself, and took my
place on the heated pavement beside the woman and her child; then
as gently and as kindly as I could I asked his name and age.
"He is four years old," she replied, curtly.
"And his name?"
"His name is Thook" (Sorrow), said the woman, turning away her
face.
"And why hast thou given him such a name?"
"What is that to thee, woman?" was the sharp rejoinder.
After this she relapsed into a grim silence, seeming to gaze intently
into the empty air. But at length there came a sob, and she passed
her bare arms slowly across her eyes. This served as a signal for the
little fellow to begin to scream again, which he did most lustily; the
woman, after quieting him, turned to me, and to my great surprise
began to talk of her own accord, with but few questions on my part.
"Hast thou come here to seek me, lady? Has the Naikodah, my
husband, sent thee? Tell me, is he well? Hast thou come to buy me?
Ah! lady! will thou not buy me? Will thou not help me to get my
pardon?"
"Tell me why thou art chained. What is thy crime?"
This seemed a terrible question for the poor woman. In vain she
attempted to speak; her lips moved, but uttered no sound, her
features quivered, and with one convulsive movement she threw up
her arms and burst into an agony of tears. She sobbed passionately
for some time, then, passing into a quieter mood, turned to me and
said, bitterly: "Do you want to know of what crime I am accused? It
is the crime of loving my husband and seeking to be with him."
"But what induced you to become a slave?"
"I was born a slave, lady. It was the will of Allah."
"You are a Mohammedan then?"
"My parents were Mohammedans, slaves to the father of my
mistress, Chow Chom Manda Ung. When we were yet young, my
brother and I were sent as slaves to her daughter, the Princess P'hra
Ong Brittry."
"If you can prove that your parents were Mohammedans, I can help
you, I think; because all the Mohammedans here are under British
protection, and no subject of Britain can be a slave."
"But, lady, my parents sold themselves to my mistress's
grandfather."
"That was your father's debt, which your mother and father have
paid over and over again by a life of faithful servitude. You can insist
upon your mistress accepting your purchase-money."
"Insist," said the woman, her large, dark eyes glowing with the tears
still glistening in them. "You do not know what you say. You do not
know that my mistress, Chow Chom Manda Ung, is mother-in-law to
the king, and that her daughter, Princess P'hra Ong Brittry, is his
favorite half-sister and queen. My only hope lies in a special pardon
from my mistress herself."
"And your friends," said I, "do they know nothing of your cruel
captivity?"
"Nothing, indeed. I have no opportunity to speak even to the slave-
woman whose duty it is to feed us daily. And her lot is too sad
already for her to be willing to run any great risk for me. The
secrecy and mystery of my sudden disappearance have been
preserved so long because I am chained here. No one comes here
but my mistress, and she only visits this place occasionally, with the
most tried and trusted of her slave-women."
Eleven o'clock boomed like a death-knell through the solitude. The
woman laid herself down beside her sleeping boy to rest, apparently
worn out with a sense of her misery. I placed my small umbrella
over them; and this simple act of kindness so touched the poor
thing, that she started up suddenly, and, before I could prevent her,
passionately kissed my soiled and dusty shoes.
I was so sorry for the unhappy creature that tears filled my eyes.
"My sister," said I, "tell me your whole story, and I will lay it before
the king."
The woman started up and adjusted the umbrella over the sleeping
child. Her eyes beamed with a fire as if from above, while with
wonderful power, combined with sweetness and delicacy, she
repeated her sad tale.
"There is sorrow in my heart, lady, where once there was nothing
but passive endurance. In my soul I now hear whisperings of things
that are between heaven and earth, yea, and beyond the heaven of
heavens, where once there was nothing but blind obedience.
Unconscious of the beauty of life, my heart was as if frozen and inert
until I met the Naikodah, my husband. Lady, as I told you, I and my
brother were born slaves; and so faithful were we, that my brother
obtained, as proof of the trust my lady reposed in him, the charge of
a rice plantation at Ayudia, while I was promoted to be the chief
attendant of the Princess P'hra Ong Brittry.
"One day my mistress intrusted to my care a bag of money, to
purchase some Bombay silk of the Naikodah Ibrahim. As it was the
first time for many years that I had been permitted to quit the gates
of the gloomy palace, I felt on that day as if I had come into the
world anew, as if my previous life had been nothing but a dream;
and my recollections of that day are always present to my mind, and
saying to me, 'Remember how happy you were once, be patient
now.'
"Oh! On that day the Mèinam splashed and rippled more
enchantingly, seemed broader and more beautiful, than ever! The
green leaves and buds seemed to have burst forth all of a sudden.
How beautifully green the grass was, and how clearly and joyously
the birds on the bushes and in the trees poured forth their song, as
if purposely for me, while from the distant plain across the river
floated the aromatic breath of new-blown flowers, filling me with
inexpressible delight! I was silent with a feeling of supreme
happiness. On that day a new light had risen in the east, a light
which was to enlighten and to darken all my coming life.
"We moored our boat by the bank of the river, and made our way to
the shop of the Naikodah, which my companions entered, while I sat
outside on the steps until the bargain should be completed. My
companions and the merchant could come to no terms. I entered
with the bag of money, hoping by the sight of the silver to induce
him to sell the silk for the price offered; but on entering I seemed to
be dazzled by something, I know not what. The merchant's eyes
flashed upon me, as it were, with a look of recollection, and by their
expression reminded me of some face I had seen in my infancy, or,
perhaps, in my dreams. I drew my faded, tattered scarf more tightly
around my chest, and sat down silent and wondering, not daring to
ask myself where I had seen that face before, or why it produced
such an effect upon me.
A SIAMESE FLOWER-GIRL.
"After a great deal of talking and bargaining about the silk, we came
away without it, but the next day went again to the merchant and
purchased it at his own price. I was surprised, however, to find that,
when I paid him the money, he left five ticals in my hands. 'That is
our kumrie' (perquisite), said the women, snatching the ticals out of
my hand and pocketing them. Time after time we repeated our visits
to the merchant, who was constantly kind and respectful in his
manner towards me. He always left five ticals for us. My companions
took the money, but I persistently refused to share in this pitiful kind
of profit.
"The merchant began to observe me more closely, and, as I thought,
to take an interest in me, and one day, after we had purchased
some boxes of fragrant candles and wax-tapers, and I had paid him
the full price for his goods, he left twenty ticals on the floor beside
me. My companions called my attention to the money; when the
merchant, observing my unwillingness to receive it, took up fifteen
ticals, leaving the usual kumrie of five upon the floor, which my
companions picked up and appropriated.
"We returned, as was our custom, by the river, slowly paddling our
little canoe down the broad and beautiful stream, and enjoying every
moment of our permitted freedom. I was sorely unwilling to return
to the palace; I was even tempted to plunge into the water and
make good my escape; but the responsibility of the money intrusted
to my care made me hesitate, and the tranquil surface of the
Mèinam, broken only by its circling ripples, helped to dissipate my
wicked thoughts. Still I indulged, though almost unconsciously, the
hope of obtaining my freedom some day, without even forming a
thought as to how it could ever be accomplished. How or why I
began to think of getting free I know not. I seemed to inhale a
longing for freedom with the fragrance of flowers wafted to me on
the fresh, invigorating air; every tree in blossom, every wild flower
clothed in its splendor of red and orange, made me dream as
naturally of liberty as it did of love; and I prayed for freedom for the
first time in my life, even as for the first time I felt the strength of a
supreme emotion overpowering me."
Here the woman paused for a few moments, and I was surprised to
find that she expressed herself so well, until I remembered that the
princesses of Siam make it a special point to educate the slaves born
in their household, so that in most Oriental accomplishments they
generally surpass the common people who may have become slaves
by purchase. There was something very simple and attractive in the
way she spoke of herself, and throughout our whole interview she
manifested such gentleness and resignation that she completely won
my affection and pity.
After a while she smiled sadly, and said softly: "Ah, lady! we all love
God, and we are all loved by him; yet he has seen fit to make some
masters and others slaves. Strange as the delusion may appear to
you, who are free and perfectly happy, while the slave is not happy,
the more impossible seemed the realization of my hope of freedom,
the more I thought of it and longed for it.
"One day a slave-woman came to my mistress with some new goods
from the Naikodah, and on seeing me she begged for a drink of
water and some cere (betel-leaf). As I handed her the water, she
said to me in a low tone: 'Thou art a Moslem; free thyself from this
bondage to an unbelieving race. Take from my master the price of
thy freedom; come out of this Naiwang (palace) and be restored to
the true people of God.'
"I listened in amazement, fearing to break the enchanting spell of
her words, and hardly believing that I had heard aright. She quitted
me suddenly, fearful of exciting suspicion, and left me in such a
disturbed state of mind as I had never before experienced. My
thoughts flew hither and thither like birds overtaken by a sudden
storm, flapping their silent and despairing wings against the closed
and barred gates of my prison. I found comfort only in trusting to
the Great Heart above, and with the instinct of all sufferers I turned
at once to him.
"When I saw the woman a second time I embraced the opportunity
to say to her, 'Sister, tell me, how shall I obtain my purchase-money?
Will not thy master hold me as his slave?'
"'He will give thee the money, and will never repent having freed a
Moslem and the daughter of a believer from slavery.'
"'O thou angel of life!' said I, clasping her to my throbbing heart, 'I
am already his slave.'
"She released my arms from around her neck, and, taking some
silver from her scarf, tied it firmly into mine without another word;
and I, fearing lest I should be discovered with so much money in my
possession, came here by night and hid it under this very pavement
on which we are seated.
"Some weeks after we were sent again to the Naikodah to buy some
sandal-wood tapers and flowers for the cremation of the young
Princess P'hra Ong O'Dong. I never was so conscious of the
shabbiness of my dress as when I entered the presence of the good
merchant. We made our purchase, paid the money, and as I rose to
depart, my friend D'hamni, the slave-woman who had been
employed by the Naikodah to speak to me, beckoned me to come
into an inner chamber. I was followed by her master, who addressed
himself to me, and said,—I remember the words so well,—'L'ore!
Welcome to our website – the perfect destination for book lovers and
knowledge seekers. We believe that every book holds a new world,
offering opportunities for learning, discovery, and personal growth.
That’s why we are dedicated to bringing you a diverse collection of
books, ranging from classic literature and specialized publications to
self-development guides and children's books.
ebookbell.com