100% found this document useful (3 votes)
27 views

Object Oriented Programming With C 2 e Second Edition Sahay 2024 Scribd Download

ebook

Uploaded by

moninsvacchi
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
100% found this document useful (3 votes)
27 views

Object Oriented Programming With C 2 e Second Edition Sahay 2024 Scribd Download

ebook

Uploaded by

moninsvacchi
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 84

Full download ebook at ebookgate.

com

Object Oriented Programming with C 2 e Second


Edition Sahay

https://ebookgate.com/product/object-oriented-
programming-with-c-2-e-second-edition-sahay/

Download more ebook from https://ebookgate.com


More products digital (pdf, epub, mobi) instant
download maybe you interests ...

Object oriented programming in C 7th print. with


corrections Edition Lafore

https://ebookgate.com/product/object-oriented-programming-
in-c-7th-print-with-corrections-edition-lafore/

Object oriented programming with ABAP Objects 1st


Edition James Wood

https://ebookgate.com/product/object-oriented-programming-with-
abap-objects-1st-edition-james-wood/

Beginning C 3 0 an introduction to object oriented


programming 1st Edition Jack Purdum

https://ebookgate.com/product/beginning-c-3-0-an-introduction-to-
object-oriented-programming-1st-edition-jack-purdum/

Object oriented Analysis And Design Understanding


System Development With UML 2 0 First Edition Mike
O'Docherty

https://ebookgate.com/product/object-oriented-analysis-and-
design-understanding-system-development-with-uml-2-0-first-
edition-mike-odocherty/
Object Oriented Oracle Wenny Rahayu

https://ebookgate.com/product/object-oriented-oracle-wenny-
rahayu/

ActionScript 3 0 design patterns object oriented


programming techniques 1st ed Edition William Sanders

https://ebookgate.com/product/actionscript-3-0-design-patterns-
object-oriented-programming-techniques-1st-ed-edition-william-
sanders/

Programming ArcObjects with VBA a task oriented


approach Chang

https://ebookgate.com/product/programming-arcobjects-with-vba-a-
task-oriented-approach-chang/

Programming in Objective C 2. print. with corr.,


Nachdr. Edition Kochan

https://ebookgate.com/product/programming-in-objective-c-2-print-
with-corr-nachdr-edition-kochan/

The principles of object oriented JavaScript Zakas

https://ebookgate.com/product/the-principles-of-object-oriented-
javascript-zakas/
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

© Oxford University Press 2006, 2012

The moral rights of the author/s have been asserted.

First Edition Published in 2006


Second Edition Published in 2012

All rights reserved. No part of this publication may be reproduced, stored in


a retrieval system, or transmitted, in any form or by any means, without the
prior permission in writing of Oxford University Press, or as expressly permitted
by law, by licence, or under terms agreed with the appropriate reprographics
rights organization. Enquiries concerning reproduction outside the scope of the
above should be sent to the Rights Department, Oxford University Press, at the
address above.

You must not circulate this work in any other form


and you must impose this same condition on any acquirer.

ISBN-13: 978-0-19-806530-2
ISBN-10: 0-19-806530-2

Typeset in Times New Roman


by Recto Graphics, Delhi 110096
Printed in India by Adage Printers (P) Ltd., Noida 201301 U.P.
Preface to the First Edition

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.

About the Book

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

The object-oriented programming system (OOPS) enables a programmer to model real-world


objects. It allows the programmer to add characteristics like data security, data encapsulation,
etc.
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 then work
upon them. The code design is centered around procedures. While this may sound obvious,
this programming pattern has its drawbacks, a major one being that the data is not secure. It
can be manipulated by any procedure.
It is the lack of data security of the procedure-oriented programming system that led to
OOPS, in which, with the help of a new programming construct and new keywords, associated
functions of the data structure can be given exclusive rights to work upon its variables.
There is another characteristic of real-world objects—a guaranteed initialization of data.
Programming languages that implement OOPS enable library programmers to incorporate this
characteristic of real-world objects into structure variables. Library programmers can ensure
a guaranteed initialization of data members of structure variables to the desired values. For
this, application programmers do not need to write code explicitly.
OOPS further supports the following concepts:
x Inheritance This feature allows a class to inherit the data and function members of an
existing class.
x Data abstraction Data abstraction is a virtue by which an object hides its internal
operations from the rest of the program.
x Modularity This feature supports dividing a program into small segments and implement
those segments using different functions.
x Polymorphism Through polymorphism, functions with different set of formal arguments
can have the same name.
The ¿rst edition had covered the fundamentals of the object oriented programming system
in depth. These explanations in the ¿rst edition hold true for any programming language that
supports OOPS. This second edition enhances coverage, as listed below.

New to this Edition


x New chapter on data structures containing new and original algorithms, especially an
elegant and simple recursive algorithm for inserting nodes into trees. The explanations
are elaborate and full of diagrams.
x New sections on explicit constructors, command line arguments, and re-throwing
exceptions.
iv 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.

Organization of the Book


A brief knowledge of C language is a prerequisite for this book. The readers need to know
how programs are written in C, data types, decision-making and looping constructs, operators,
functions, header ¿les, pointers, and structures.
Chapter 1 contains an explanation of the procedure-oriented programming system, the
role played by structures in this system, its drawbacks and how these drawbacks led to the
creation of OOPS. The meaning and method of modelling real-world objects by the object-
oriented programming system have been clearly explained. The chapter includes a study of
the non-object-oriented features of C++.
Chapter 2 is devoted to the study of objects and classes. It gives a thorough explanation
of the class construct of C++. Superiority of the class construct of C++ over the structure
construct of C language is explained. A description of the various types and features of member
functions and member data is included. Other concepts included are namespaces, arrays of
objects, arrays in objects, and nested classes.
Chapter 3 deals with dynamic memory management. It explains the use of the new and the
delete operators. It also explains the method of specifying our own new handler for handling
out-of-memory conditions.
Chapter 4 explains constructors and destructors. It discusses their importance, their features,
and the method of de¿ning them.
Chapter 5 is devoted to inheritance. Concepts like base class, derived class, base class
pointer, and derived class pointer are covered. The protected keyword and the implications
of deriving by different access speci¿ers are explained. This chapter describes various types
of inheritance.
Chapter 6 gives a detailed explanation of one of the most striking features of C++—
dynamic polymorphism. This chapter describes the virtual functions and how it enables C++
programmers to extend class libraries. The importance of pure virtual functions and clone
functions is also explained.
Chapter 7 describes the standard C++ library for handling streams. It explains the two
types of input and output—text mode and binary mode. Input and output from disk ¿les are
explained. The chapter also describes the use of error-handling routines of the standard C++
stream library and manipulators.
Chapter 8 is devoted to operator overloading, type conversion, new style casts, and RTTI.
This chapter explains the various intricacies and the proper use of operator overloading.
This chapter also explains how a C++ programmer can implement conventional style type
Preface to the Second Edition v

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

Preface to the Second Edition iii

Preface to the First Edition vi

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

Appendix A: Case Study—A Word Query System 417


Appendix B: Comparison of C++ with C 425
Appendix C: Comparison of C++ with Java 427
Appendix D: Object-Oriented Analysis and Design 437
Appendix E: Glossary 449
Appendix F: Self Tests 454

Bibliography 460

Index 461
Detailed Contents

Preface to the Second Edition iii


Preface to the First Edition vi
Brief Contents ix

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

2. Classes and Objects 31


2.1 Introduction to Classes and Objects 31
2.1.1 Private and Public Members 33
2.1.2 Objects 36
2.1.3 Scope Resolution Operator 37
2.1.4 Creating Libraries Using the Scope Resolution Operator 38
2.1.5 Using Classes in Application Programs 39
2.1.6 this Pointer 40
2.1.7 Data Abstraction 45
2.1.8 Explicit Address Manipulation 47
2.1.9 Arrow Operator 47
2.1.10 Calling One Member Function from Another 48
xii Detailed Contents

2.2 Member Functions and Member Data 49


2.2.1 Overloaded Member Functions 49
2.2.2 Default Values for Formal Arguments of Member Functions 51
2.2.3 Inline Member Functions 52
2.2.4 Constant Member Functions 52
2.2.5 Mutable Data Members 54
2.2.6 Friends 54
2.2.7 Static Members 59
2.3 Objects and Functions 65
2.4 Objects and Arrays 66
2.4.1 Arrays of Objects 67
2.4.2 Arrays Inside Objects 67
2.5 Namespaces 68
2.6 Nested Inner Classes 71

3. Dynamic Memory Management 78


3.1 Introduction 78
3.2 Dynamic Memory Allocation 79
3.3 Dynamic Memory Deallocation 84
3.4 set_new_handler() function 88

4. Constructors and Destructors 92


4.1 Constructors 92
4.1.1 Zero-argument Constructor 94
4.1.2 Parameterized Constructors 97
4.1.3 Explicit Constructors 103
4.1.4 Copy Constructor 105
4.2 Destructors 109
4.3 Philosophy of OOPS 112

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

5.7.3 Multi-level Inheritance 145


5.7.4 Hierarchical Inheritance 147
5.7.5 Hybrid Inheritance 148
5.8 Order of Invocation of Constructors and Destructors 149

6. Virtual Functions and Dynamic Polymorphism 153


6.1 Need for Virtual Functions 153
6.2 Virtual Functions 156
6.3 Mechanism of Virtual Functions 160
6.4 Pure Virtual Functions 162
6.5 Virtual Destructors and Virtual Constructors 167
6.5.1 Virtual Destructors 167
6.5.2 Virtual Constructors 168

7. Stream and File Handling 172


7.1 Streams 172
7.2 Class Hierarchy for Handling Streams 172
7.3 Text and Binary Input/Output 174
7.3.1 Data Storage in Memory 174
7.3.2 Input/Output of Character Data 175
7.3.3 Input/Output of Numeric Data 175
7.3.4 Note on Opening Disk Files for I/O 176
7.4 Text Versus Binary Files 176
7.5 Text Output/Input 177
7.5.1 Text Output 177
7.5.2 Text Input 181
7.6 Binary Output/Input 185
7.6.1 Binary Output—write() Function 185
7.6.2 Binary Input—read() Function 189
7.7 Opening and Closing Files 193
7.7.1 open() Function 193
7.7.2 close() Function 194
7.8 Files as Objects of the fstream Class 194
7.9 File Pointers 194
7.9.1 seekp() Function 195
7.9.2 tellp() Function 196
7.9.3 seekg() Function 196
7.9.4 tellg() Function 196
7.10 Random Access to Files 197
7.11 Object Input/Output Through Member Functions 197
7.12 Error Handling 199
7.12.1 eof() Function 199
7.12.2 fail() Function 199
7.12.3 bad() Function 200
7.12.4 clear() Function 200
7.13 Manipulators 201
7.13.1 Pre-de¿ned Manipulators 201
xiv Detailed Contents

7.13.2 User-de¿ned Manipulators 203


7.14 Command Line Arguments 204

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

9. Data Structures 283


9.1 Introduction 283
9.2 Linked Lists 284
9.3 Stacks 336
9.4 Queues 340
9.5 Trees 343
9.5.1 Binary Trees 344
9.5.2 Binary Search Trees 347

10. Templates 372


10.1 Introduction 372
10.2 Function Templates 373
10.3 Class Templates 378
10.3.1 Nested Class Templates 382
10.4 Standard Template Library 382
10.4.1 list Class 383
Detailed Contents xv

10.4.2 vector Class 386


10.4.3 pair Class 387
10.4.4 map Class 387
10.4.5 set Class 389
10.4.6 multimap Class 389
10.4.7 multiset Class 390

11. Exception Handling 393


11.1 Introduction 393
11.2 C-Style Handling of Error-generating Code 394
11.2.1 Terminate the Program 394
11.2.2 Check the Parameters before Function Call 395
11.2.3 Return a Value Representing an Error 396
11.3 C++-Style Solution—the try/throw/catch Construct 397
11.3.1 It is Necessary to Catch Exceptions 400
11.3.2 Unwinding of the Stack 401
11.3.3 Need to Throw Class Objects 404
11.3.4 Accessing the Thrown Object in the Catch Block 406
11.3.5 Throwing Parameterized Objects of a Nested Exception Class 408
11.3.6 Catching Uncaught Exceptions 409
11.3.7 Re-throwing Exceptions 410
11.4 Limitation of Exception Handling 414

Appendix A: Case Study—A Word Query System 417


Problem Statement 417
A Sample Run 417
The Source Code 418
Explanation of the Code 420

Appendix B: Comparison of C++ with C 425


Non-object-oriented Features Provided in C++ that are Absent in C
Language 425
Object-oriented Features Provided in C++ to make it Comply with the
Requirements of the Object-Oriented Programming System 426

Appendix C: Comparison of C++ with Java 427


C.1 Similarities between C++ and Java 427
C.2 Differences between C++ and Java 428

Appendix D: Object-Oriented Analysis and Design 437


D.1 Introduction 437
Why Build Models? 437
Overview of OOAD 437
D.2 Object-Oriented Model 438
Object Model 438
Dynamic Model 442
Functional Model 444
D.3 Analysis 446
xvi Detailed Contents

Overview of Analysis 446


Object Modelling 446
Dynamic Modelling 446
Functional Modelling 447
D.4 System Design 447
Breaking the System into Sub-systems 447
Layers 447
Partitions 447
D.5 Object Design 448
Overview of Object Design 448
D.6 Implementation 448

Appendix E: Glossary 449

Appendix F: Self Tests 454


Test 1 454
Test 2 456
Test 3 458

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.)

1.1 A Review of Structures


In order to understand procedure-oriented programming systems, let us ¿rst recapitulate our
understanding of structures in C. Let us review their necessity and use in creating new data
types.

1.1.1 The Need for Structures


There are cases where the value of one variable depends upon that of another variable.
Take the example of date. A date can be programmatically represented in C by three
different integer variables taken together. Say,
int d,m,y; //three integers for representing dates

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

and we call the function as


next_day(&d,&m,&y);

‘d’ will become 1, ‘m’ will become 3, and ‘y’ will remain 1999.
Again, if
d=31;
m=12;
y=1999; //31st December, 1999

and we call the function as


next_day(&d,&m,&y);

‘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)!

Listing 1.1 Problem in passing groups of programmatically independent but logically


dependent variable
d1=28; m1=2; y1=1999; //28th February, 1999
d2=19; m2=3; y2=1999; //19th March, 1999
next_day(&d1,&m1,&y1); //OK
next_day(&d1,&m2,&y2); //What? Incorrect set passed!

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 *);

Let us declare date as an array of three integers.


int date[3];
date[0]=28;
date[1]=2;
date[2]=1999; //28th February, 1999
Introduction to C++ 3

Now, let us call the function as follows:


next_day(date);

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 *);

Let us now call it as shown in Listing 1.2.

Listing 1.2 The need for structures

struct date d1;


d1.d=28;
d1.m=2;
d1.y=1999;
next_day(&d1);

‘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++

1.1.2 Creating a New Data Type Using Structures


Creation of a new data type using structures is loosely a three-step process that is executed
by the library programmer.
Step 1: Put the structure de¿nition and the prototypes of the associated functions in a header
¿le, as shown in Listing 1.3.
Listing 1.3 Header file containing definition of a structure variable and prototypes of its
associated functions
/*Beginning of date.h*/
/*This file contains the structure definition and
prototypes of its associated functions*/
struct date
{
int d,m,y;
};
void next_day(struct date *); //get the next date
void get_sys_date(struct date *); //get the current
//system date
/*
Prototypes of other useful and relevant functions to
work upon variables of the date structure
*/
/*End of date.h*/

Step 2: As shown in Listing 1.4, put the de¿nition of the associated functions in a source
code and create a library.

Listing 1.4 Defining the associated functions of a structure

/*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

1.1.3 Using Structures in Application Programs


The steps to use this new data type are as follows:
Step 1: Include the header ¿le provided by the library programmer in the source code.
/*Beginning of dateUser.c*/
#include“date.h”
void main( )
{
. . . .
. . . .
}
/*End of dateUser.c*/

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.

Listing 1.5 Using a structure in an application program

/*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*/

Step 4: Compile the source code to get the object ¿le.


Step 5: Link the object ¿le with the library provided by the library programmer to get the
executable or another library.

1.2 Procedure-Oriented Programming Systems


In light of the previous discussion, let us understand the procedure-oriented programming
system. The foregoing pattern of programming divides the code into functions. Data (contained
in structure variables) is passed from one function to another to be read from or written into.
The focus is on procedures. This programming pattern is, therefore, a feature of the procedure-
oriented programming system.
6 Object-Oriented Programming with 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

1.3 Object-Oriented Programming Systems


In OOPS, we try to model real-world objects. But, what are real-world objects? Most real-
world objects have internal parts and interfaces that enable us to operate them. These interfaces
perfectly manipulate the internal parts of the objects. They also have the exclusive rights to
do so.
Let us understand this concept with the help of an example. Take the case of a simple
LCD projector (a real-world object). It has a fan and a lamp. There are two switches—one to
operate the fan and the other to operate the lamp. However, the operation of these switches is
necessarily governed by rules. If the lamp is switched on, the fan should automatically switch
itself on. Otherwise, the LCD projector will get damaged. For the same reason, the lamp should
automatically get switched off if the fan is switched off. In order to cater to these conditions,
the switches are suitably linked with each other. The interface to the LCD projector is perfect.
Further, this interface has the exclusive rights to operate the lamp and fan.
This, in fact, is a common characteristic of all real-world objects. If a perfect interface is
required to work on an object, it will also have exclusive rights to do so.
Coming back to C++ programming, we notice a resemblance between the observed
behaviour of the LCD projector and the desired behaviour of data structure’s variables. In
OOPS, with the help of a new programming construct and new keywords, associated functions
of the data structure can be given exclusive rights to work upon its variables. In other words,
all other pieces of code can be prevented from accessing the data members of the variables
of this structure.
Compilers that implement OOPS enable data security by diligently enforcing this
prohibition. They do this by throwing compile-time errors against pieces of code that violate
the prohibition. This prohibition, if enforced, will make structure variables behave like real-
world objects. Associated functions that are de¿ned to perfectly manipulate structure variables
can be given exclusive rights to do so.
There is still another characteristic of real-world objects—a guaranteed initialization of
data. After all, when you connect the LCD projector to the mains, it does not start up in an
invalid state (fan off and lamp on). By default, either both the lamp and the fan are off or
both are on. Users of the LCD projector need not do this explicitly. The same characteristic
is found in all real-world objects.
Programming languages that implement OOPS enable library programmers to incorporate
this characteristic of real-world objects into structure variables. Library programmers can
ensure a guaranteed initialization of data members of structure variables to the desired values.
For this, application programmers do not need to write code explicitly.
Two more features are incidental to OOPS. They are:
x Inheritance
x Polymorphism
Inheritance allows one structure to inherit the characteristics of an existing structure.
As we know from our knowledge of structures, a variable of the new structure will contain
data members mentioned in the new structure’s de¿nition. However, because of inheritance,
it will also contain data members mentioned in the existing structure’s de¿nition from which
the new structure has inherited.
Further, associated functions of the new structure can work upon 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 new structure. Again, as a result of inheritance, associated functions of the
existing structure from which the new structure has inherited will also be able to work upon
8 Object-Oriented Programming with C++

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.

1.4 Comparison of C++ with C


C++ is an extension of C language. It is a proper superset of C language. This means that
a C++ compiler can compile programs written in C language. However, the reverse is not
true. A C++ compiler can understand all the keywords that a C compiler can understand.
Again, the reverse is not true. Decision-making constructs, looping constructs, structures,
functions, etc. are written in exactly the same way in C++ as they are in C language. Apart
from the keywords that implement these common programming constructs, C++ provides
a number of additional keywords and language constructs that enable it to implement the
object-oriented paradigm.
The header ¿le given in Listing 1.6 shows how the structure Date, which has been our
running example so far, can be rewritten in C++.
Listing 1.6 Redefining the Date structure in C++

/*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.

1.5 Console Input/Output in C++


This section discusses console input and output in C++.

1.5.1 Console Output


The output functions in C language, such as printf(), can be included in C++ programs
because they are anyway de¿ned in the standard library. However, there are some more ways
of outputting to the console in C++. Let us consider an example (see Listing 1.7).

Listing 1.7 Outputting in C++

/*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.

Listing 1.8 Inserting new line by ‘endl’

/*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.

Listing 1.9 Outputting data with the insertion operator

/*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.

Listing 1.10 Cascading the insertion operator

/*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.

Listing 1.11 Outputting constants using the insertion operator

/*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.

1.5.2 Console Input


The input functions in C language, such as scanf(), can be included in C++ programs because
they are anyway de¿ned in the standard library. However, we do have some more ways of
inputting from the console in C++. Let us consider an example.

Listing 1.12 Inputting in C++

/*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.

Listing 1.13 Inputting data with the extraction operator

/*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.

Listing 1.14 Cascading the extraction operator

/*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.

1.6 Variables in C++


Variables in C++ can be declared anywhere inside a function and not necessarily at its very
beginning. For example, see Listing 1.15.
14 Object-Oriented Programming with C++

Listing 1.15 Declaring variables in C++

#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

1.7 Reference Variables in C++


First, let us understand the basics. How does the operating system (OS) display the value of
variables? How are assignment operations such as ‘x=y’ executed during run time? A detailed
answer to these questions is beyond the scope of this book. A brief study is, nevertheless,
possible and necessary for a good understanding of reference variables. What follows is a
simpli¿ed and tailored explanation.
The OS maintains the addresses of each variable as it allocates memory for them during run
time. In order to access the value of a variable, the OS ¿rst ¿nds the address of the variable
and then transfers control to the byte whose address matches that of the variable.
Suppose the following statement is executed (‘x’ and ‘y’ are integer type variables).
x=y;

The steps followed are:


1. The OS first finds the address of ‘y’.
2. The OS transfers control to the byte whose address matches this address.
3. The OS reads the value from the block of four bytes that starts with this byte (most C++
compilers cause integer-type variables to occupy four bytes during run time and we will
accept this value for our purpose).
4. The OS pushes the read value into a temporary stack.
5. The OS finds the address of ‘x’.
6. The OS transfers control to the byte whose address matches this address.
7. The OS copies the value from the stack, where it had put it earlier, into the block of four
bytes that starts with the byte whose address it has found above (address of ‘x’).
Notice that addresses of the variables on the left as well as on the right of the assignment
operator are determined. However, the value of the right-hand operand is also determined. The
expression on the right must be capable of being evaluated to a value. This is an important
point and must be borne in mind. It will enable us to understand a number of concepts later.
Introduction to C++ 15

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.

Listing 1.16 Reference variables

/*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.

Listing 1.17 Reading the value of a reference variable

/*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.

Listing 1.18 Passing by reference

/*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

Functions can return by reference also. See Listing 1.19.

Listing 1.19 Returning by reference

/*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

int & larger(int & a, int & b)


{
if(a>b) //return a reference to the larger parameter
return a;
else
return b;
}
/*End of reference04.cpp*/

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.

Listing 1.20 Returning by reference

/*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.

Listing 1.21 Returning the reference of a local variable

/*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.

1.8 Function Prototyping


Function prototyping is necessary in C++. A prototype describes the function’s interface to
the compiler. It tells the compiler the return type of the function as well as the number, type,
and sequence of its formal arguments.
The general syntax of function prototype is as follows:
return_type function_name(argument_list);
For example,
int add(int, int);

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.

Listing 1.22 Function prototyping

/*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

Why is prototyping important? By making prototyping necessary, the compiler ensures


the following:
20 Object-Oriented Programming with C++

x The return value of a function is handled correctly.


x Correct number and type of arguments are passed to a function.
Let us discuss these points.
Consider the following statement in Listing 1.22:
int add(int, int);

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.

Listing 1.23 Absence of function prototype produces weird results

/*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.

1.9 Function Overloading


C++ allows two or more functions to have the same name. For this, however, they must have
different signatures. Signature of a function means the number, type, and sequence of formal
arguments of the function. In order to distinguish amongst the functions with the same name,
the compiler expects their signatures to be different. Depending upon the type of parameters
that are passed to the function call, the compiler decides which of the available de¿nitions
22 Object-Oriented Programming with C++

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.

Listing 1.24 Function overloading

/*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);

is also handled by the compiler and the linker.


Introduction to C++ 23

Note the importance of function prototyping. Since function prototyping is mandatory in


C++, it is possible for the compiler to support function overloading properly. The compiler
is able to not only restrict the number of ways in which a function can be called but also
support more than one way in which a function can be called. Function overloading is possible
because of the necessity to prototype functions.
By itself, function overloading is of little use. Instead of giving exactly the same name for
functions that perform similar tasks, it is always possible for us to give them similar names.
However, function overloading enables the C++ compiler to support another feature, that
is, function overriding (which in turn is not really a very useful thing by itself but forms the
basis for dynamic polymorphism—one of the most striking features of C++ that promotes
code reuse).
Function overloading is also known as function polymorphism because, just like
polymorphism in the real world where an entity exists in more than one form, the same
function name carries different meanings.
Function polymorphism is static in nature because the function de¿nition to be executed
is selected by the compiler during compile time itself. Thus, an overloaded function is said
to exhibit static polymorphism.

1.10 Default Values for Formal Arguments of Functions


It is possible to specify default values for some or all of the formal arguments of a function. If
no value is passed for an argument when the function is called, the default value speci¿ed for
it is passed. If parameters are passed in the normal fashion for such an argument, the default
value is ignored. Listing 1.25 is an illustrative example.

Listing 1.25 Default values for function arguments

/*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.

Listing 1.26 Default values for more than one argument

/*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);

can be written instead of


int add(int,int b=0,int c=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’);

1.11 Inline Functions


Inline functions are used to increase the speed of execution of the executable ¿les. C++ inserts
calls to the normal functions and the inline functions in different ways in an executable.
The executable program that is created after compiling the various source codes and linking
them consists of a set of machine language instructions. When a program is started, the
operating system loads these instructions into the computer’s memory. Thus, each instruction
has a particular memory address. The computer then goes through these instructions one by
one. If there are any instructions to branch out or loop, the control skips over instructions and
jumps backward or forward as needed. When a program reaches the function call instruction,
it stores the memory address of the instruction immediately following the function call. It then
jumps to the beginning of the function, whose address it ¿nds in the function call instruction
itself, executes the function code, and jumps back to the instruction whose address it had
saved earlier.
Obviously, an overhead is involved in
x making the control jump back and forth and
26 Object-Oriented Programming with C++

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!

Figure 1.1 Transfer of control in a non-inline function


Introduction to C++ 27

Figure 1.2 Control does not get transferred in an inline function

Listing 1.27 Inline functions

/*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.

2.1 Introduction to Classes and Objects


Classes are to C++ what structures are to C. Both provide the library programmer a means
to create new data types.
Let us brieÀy recapitulate the issues faced while programming in C described in the previous
chapter. In C, the library programmer creates structures. He/she also provides a set of tested
bug-free functions that correctly manipulate the data members of structure variables.
The Date structure and its accompanying functions may be perfect. However, there is
absolutely no guarantee that the client programs will use only these functions to manipulate
the members of variables of the structure. See Listing 2.1.
32 Object-Oriented Programming with C++

Listing 2.1 Undesirable manipulation of structures not prevented in C

struct Date d1;


setDate(&d1); //assign system date to d1.
printf(“%d”,d1.month);
d1.month = 13; //undesirable but unpreventable!!

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.

Listing 2.2 C++ allows member functions in structures

/*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!!

2.1.1 Private and Public Members

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.

Listing 2.3 Making members of structures private

/*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.

Listing 2.4 Structure members are public by default

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;
}
};

can also be written as


struct Distance
{
void setFeet(int x) //public by default
{
iFeet=x;
}
int getFeet() //public by default
{
return iFeet;
}
void setInches(float y) //public by default
{
fInches=y;
}
float getInches() //public by default
{
return fInches;
}
private:
int iFeet;
float 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.

Listing 2.5 Class members are private by default

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()
{
Another random document with
no related content on Scribd:
she objected to “Satan’s Kingdom Aristocratical,” on the score of its
halting measures.
The most striking characteristic of our Quaker diarist is precisely
this clear, cold, unbiased judgment, this sanity of a well-ordered
mind. What she lacks, what the journal lacks from beginning to end,
is some touch of human and ill-repressed emotion, some word of
pleasant folly, some weakness left undisguised and unrepented. The
attitude maintained throughout is too judicial, the repose of heart
and soul too absolute to be endearing. Here is a significant entry,
illustrating as well as any other this nicely balanced nature, which
gave to all just what was due, and nothing more:—
“There has been a disorder lately among ye cats. Our poor old
Puss, who has been for some time past unwell, died this morning, in
ye 13th year of her age. Peter dug a grave two feet deep on ye bank
in our garden, under ye stable window, where E. S., Peter and I saw
her decently interred. I had as good a regard for her as was
necessary.”
Was ever affection meted out like this? Was there ever such
Quaker-like precision of esteem? For thirteen years that cat had
been Elizabeth Drinker’s companion, and she had acquired for her
just as good a regard as was necessary, and no more. It was not
thus Sir Walter spoke, when Hinse of Hinsdale lay dead beneath the
windows of Abbotsford, slain by the great staghound, Nimrod. It was
not thus that M. Gautier lamented the consumptive Pierrot. It is not
thus that the heart mourns, when a little figure, friendly and familiar,
sits no longer by our desolate hearth.
FRENCH LOVE-SONGS

Quand on est coquette, il faut être sage;


L’oiseau de passage
Qui vole à plein cœur
Ne dort pas en l’air comme une hirondelle,
Et peut, d’un coup d’aile,
Briser une fleur.
—Alfred de Musset.

The literature of a nation is rooted in national characteristics. Foreign


influences may dominate it for a time; but that which is born of the
soil is imperishable, and must, by virtue of tenacity, conquer in the
end. England, after the Restoration, tried very hard to be French,
and the “happy and unreflecting wantonness” of her earlier song
was chilled into sobriety by the measured cadences of Gallic verse;
yet the painful and perverse effort to adjust herself to strange
conditions left her more triumphantly English than before. We are
tethered to our kind, and the wisest of all wise limitations is that
which holds us well within the sphere of natural and harmonious
development.
It is true, however, that nationality betrays itself less in lyrics,
and, above all, less in love lyrics, than in any other form of literature.
Love is a malady, the common symptoms of which are the same in
all patients; and though love-songs—like battle-songs and drinking-
songs—are seldom legitimate offsprings of experience, they are
efforts to express in words that sweet and transient pain. “Les âmes
bien nées”—without regard to birthplace—clearly of their passion,
and seek their “petit coin de bonheur” under Southern and Northern
skies. The Latin races have, indeed, depths of reserve underlying
their apparent frankness, and the Saxons have a genius for self-
revelation underlying their apparent reticence; but these traits count
for little in the refined duplicity of the love-song.
Garde bien ta belle folie!
has been its burden ever since it was first chanted by minstrel lips.
M. Brunetière frankly admits the inferiority of the French lyric, an
inferiority which he attributes to the predominance of social
characteristics in the literature, as in the life of France. When poetry
is compelled to fulfil a social function, to express social conditions
and social truths, to emphasize fundamental principles and balance
contrasted forces, the founts of lyrical inspiration are early dried.
Individualism is their source,—the sharp, clear striking of the
personal note; and the English, says M. Brunetière, excel in this
regard. “To Lucasta. Going to the Warres,” has no perfect
counterpart in the love-songs of other lands.
Even the eager desire of the Frenchman to be always intelligible
(“That which is not lucid is not French”) militates against the
perfection of the lyric. So too does his exquisite and inborn sense of
proportion. “Measure,” says Mr. Brownell, “is a French passion;” but
it is a passion that refuses to lend itself to rapturous sentiment.
Et veut que l’on soit sage avec sobriété
is hardly a maxim to which the genius of the love-song gives willing
ear. Rather is she the La Belle Dame sans Merci, or the Elfin Lady
who rode through the forests of ancient France.

My sire is the nightingale,


That sings, making his wail,
In the wild wood, clear;
The mermaid is mother to me,
That sings in the salt sea,
In the ocean mere.
“What,” asks Mr. Brownell hopelessly, “has become of this Celtic
strain in the French nature?”—a strain which found vent in the
“poésie courtoise,” playful, amorous, laden with delicate subtleties
and fond conceits. This poesie—once the delight of Christendom—
echoes still in Petrarch’s sonnets and in Shakespeare’s madrigals; but
it is difficult to link its sweet extravagances with the chiselled verse
of later days, and critics forget the past in their careful
contemplation of the present. “French poetry,” says Mr. Zangwill,
“has always leant to the frigid, the academic, the rhetorical,—in a
word, to the prosaic. The spirit of Boileau has ruled it from his cold
marble urn.”
But long before Boileau lay in his urn—or in his cradle—the poets
of France, like the poets of Albion, sang with facile grace of love,
and dalliance, and the glory of youth and spring. The fact that
Boileau ignored and despised their song, and taught his obedient
followers to ignore and despise it also, cannot silence those early
notes. When he descended frigidly to his grave, Euterpe tucked up
her loosened hair, and sandalled her bare white feet, and girdled her
disordered robes into decent folds. Perhaps it was high time for
these reforms. Nothing is less seductive in middle age than the
careless gayety of youth. But once France was young, and Euterpe a
slip of a girl, and no grim shadow of that classic urn rested on the
golden days when Aucassin—model of defiant and conquering lovers
—followed Nicolette into the deep, mysterious woods.

Jeunesse sur moy a puissance,


Mais Vieillesse fait son effort
De m’avoir en sa gouvernance,

sang Charles d’Orléans, embodying in three lines the whole history


of man and song. Youth was lusty and folly riotous when Ronsard’s
mistress woke in the morning, and found Apollo waiting patiently to
fill his quiver with arrows from her eyes; or when Jacques Tahureau
watched the stars of heaven grow dim before his lady’s brightness;
or when Vauquelin de la Fresnaye saw Philis sleeping on a bed of
lilies, regardless of discomfort, and surrounded by infant Loves.

J’admirois toutes ces beautez


Égalles à mes loyautez,
Quand l’esprit me dist en l’oreille:
Fol, que fais-tu? Le temps perdu
Souvent est chèrement vendu;
S’on le recouvre, c’est merveille.

Alors, je m’abbaissai tout bas,


Sans bruit je marchai pas à pas,
Et baisai ses lèvres pourprines:
Savourant un tel bien, je dis
Que tel est dans le Paradis
Le plaisir des âmes divines.

With just such sweet absurdities, such pardonable insincerities,


the poets of Elizabeth’s England fill their amorous verse. George
Gascoigne “swims in heaven” if his mistress smiles upon him; John
Lyly unhesitatingly asserts that Daphne’s voice “tunes all the
spheres;” and Lodge exhausts the resources of the vegetable and
mineral kingdoms in searching for comparisons by which to set forth
the beauties of Rosalind. The philosophy of love is alike on both
sides of the Channel, and expressed in much the same terms of soft
insistence. Carpe diem is, and has always been, the lover’s maxim;
and the irresistible eloquence of the lyric resolves itself finally into
these two words of warning, whether urged by Celt or Saxon.
Herrick is well aware of their supreme significance when he sings:—
Gather ye rose-buds while ye may,
Old Time is still a-flying:
And this same flower that smiles to-day,
To-morrow will be dying.

Then be not coy, but use your time,


And while ye may, go marry;
For having lost but once your prime,
You may forever tarry.

Ronsard, pleading with his mistress, strikes the same relentless


note:—

Donc, si vous me croyez, Mignonne,


Tandis que vostre âge fleuronne
En sa plus vert nouveauté,
Cueillez, cueillez vostre jeunesse;
Comme à cette fleur, la vieillesse
Fera ternir vostre beauté.

May-day comes alike in England and in France. Herrick and Jean


Passerat, poets of Devonshire and of Champagne, are equally
determined that two fair sluggards, who love their pillows better
than the dewy grass, shall rise from bed, and share with them the
sparkling rapture of the early dawn. Herrick’s verse, laden with the
freshness of the Spring, rings imperatively in Corinna’s sleepy ears:—
Get up, get up, for shame! The blooming Morn
Upon her wings presents the god unshorn.
See how Aurora throws her fair
Fresh-quilted colours through the air.
Get up, sweet Slug-a-bed, and see
The dew bespangling herb and tree.

And then—across the gayety of the song—the deepening note of


persuasion strikes a familiar chord:—

Come, let us go, while we are in our prime;


And take the harmless folly of the time!
We shall grow old apace, and die
Before we know our liberty.

Passerat is no less insistent. The suitors of the sixteenth and


seventeenth centuries seem to have dedicated the chill hours of
early morning to their courtship. Nor was the custom purely pastoral
and poetic. When Lovelace makes his appointments with Clarissa
Harlowe at five A. M., the modern reader—if Richardson has a
modern reader—is wont to think the hour an unpropitious one; but
to Herrick and to the Pléiade it would have seemed rational enough.

Laissons le lit et le sommeil


Ceste journée:
Pour nous, l’Aurore au front vermeil
Est desjà née

sings the French poet beneath his lady’s window; adding, to


overcome her coyness—or her sleepiness—the old dominant
argument:—
Ce vieillard, contraire aus amans,
Des aisles porte,
Et en fuyant, nos meilleurs ans
Bien loing emporte.
Quand ridée un jour tu seras,
Mélancholique, tu diras:
J’estoy peu sage,
Qui n’usoy point de la beauté
Que si tost le temps a osté
De mon visage.

No less striking is the similarity between the reproachful couplets


in which the singers of England and of France delight in denouncing
their unfaithful fair ones, or in confessing with harmonious sighs the
transient nature of their own emotions. Inconstancy is the breath of
love’s nostrils, and the inspiration of love’s songs, which enchant us
because they express an exquisite sentiment in its brief moment of
ascendency. The tell-tale past, the dubious future, are alike
discreetly ignored. Love in the drama and in the romance plays
rather a heavy part. It is too obtrusively omniscient. It is far too self-
assertive. Yet the average taxpayer, as has been well remarked, is no
more capable of a grand passion than of a grand opera. The utmost
he can achieve is some fair, fleeting hour, and with the imperative
gladness of such an hour the love-song thrills sympathetically. It is
not its business to

recapture
That first fine careless rapture.

It does not essay the impossible.


Now the old and nameless French poet who wrote—
Femme, plaisir de demye heure,
Et ennuy qui sans fins demeure,

was perhaps too ungraciously candid. Such things, when said at all,
should be said prettily.

Sigh no more, ladies, sigh no more,—


Men were deceivers ever;
One foot in sea, and one on shore,
To one thing constant never.

Gay voices came bubbling with laughter from the happy days
that are dead. Sir John Suckling, whose admirable advice to an
overfaithful young suitor has been the most invigorating of tonics to
suitors ever since, vaunts with pardonable pride his own singleness
of heart:—

Out upon it! I have loved


Three whole days together,
And am like to love three more,
If it prove fair weather.

Time shall moult away his wings


Ere he shall discover
In the whole wide world again
Such a constant lover.

Sir John Sedley epitomizes the situation in his praises of that


jade, Phillis, whose smiles win easy pardon for her perfidy:—
She deceiving,
I believing,—
What need lovers wish for more?

And Lovelace, reversing the medal, pleads musically—and not in vain


—for the same gracious indulgence:—

Why shouldst thou sweare I am forsworn,


Since thine I vowed to be?
Lady it is already Morn,
And ’twas last night I swore to thee
That fond impossibility.

Mr. Lang is of the opinion that no Gallic verse has equalled in


audacity this confession of limitations, this “Apologia pro Vita Sua;”
and perhaps its light-heartedness is well out of general reach. But
the French lover, like the English, was made of threats and promises
alike fruitless of fulfilment, and Phillis had many a fair foreign sister,
no whit more worthy of regard. Only, amid the laughter and raillery
of a Latin people, there rings ever an undertone of regret,—not
passionate and heart-breaking, as in Drayton’s bitter cry,—
Since there’s no help, come let us kiss and part,
but vague and subtle, linking itself tenderly to some long-ignored
and half-forgotten sentiment, buried deep in the reader’s heart.
Mais où sont les neiges d’antan?
A little sob breaks the smooth sweetness of Belleau’s verse, and
Ronsard’s beautiful lines to his careless young mistress are heavy
with the burden of sighs:—
Quand vous serez bien vieille, au soir, à la chandelle,
Assise auprès du feu, devisant et filant,
Direz, chantant mes vers, en vous esmerveillant:
‘Ronsard me célébroit du temps que j’estois belle.’

The note deepens as we pass into the more conscious art of


later years, but it is always French in its grace and moderation. How
endurable is the regret with which de Musset sings of Juana, who
loved him for a whole year; how musical his farewell to Suzon,
whose briefer passion lasted eight summer days:—

Que notre amour, si tu m’oublies,


Suzon, dure encore un moment;
Comme un bouquet de fleurs pâlies;
Cache-le dans ton sein charmant!
Adieu! le bonheur reste au gîte:
Le souvenir part avec moi:
Je l’emporterai, ma petite,
Bien loin, bien vite,
Toujours à toi.

In Murger’s familiar verses, so pretty and gay and heartsick, in


the finer art of Gautier, in the cloudy lyrics of Verlaine, we catch
again and again this murmur of poignant but subdued regret, this
sigh for the light love that has so swiftly fled. The delicacy of the
sentiment is unmatched in English song. The Saxon can be
profoundly sad, and he can—or at least he could—be ringingly and
recklessly gay; but the mood which is neither sad nor gay, which is
fed by refined emotions, and tranquillized by time’s subduing touch,
has been expressed oftener and better in France. Four hundred and
fifty years ago François Villon touched this exquisite chord in his
“Ballade des Dames du Temps Jadis,” and it has vibrated gently ever
since. We hear it echoing with melancholy grace in these simple
lines of Gérard de Nerval:—

Où sont les amoureuses?


Elles sont au tombeau!
Elles sont plus heureuses,
Dans un séjour plus beau.

Nerval, like Villon, had drunk deep of the bitterness of life, but
he never permitted its dregs to pollute the clearness of his song:—
Et vent que l’on soit triste avec sobriété.
In the opinion of many critics, the lyric was not silenced, only
chilled, by the development of the classical spirit in France, and the
corresponding conversion of England. Its flute notes were heard now
and then amid the decorous couplets that delighted well-bred ears.
Waller undertook the reformation of English verse, and accomplished
it to his own and his readers’ radiant satisfaction; yet Waller’s seven-
year suit of Lady Dorothy Sidney is the perfection of that poetic love-
making which does not lead, and is not expected to lead, to
anything definite and tangible. Never were more charming tributes
laid at the feet of indifferent beauty; never was indifference received
with less concern. Sacharissa listened and smiled. The world—the
august little world of rank and distinction—listened and smiled with
her, knowing the poems were written as much for its edification as
for hers; and Waller, well pleased with the audience, nursed his
passion tenderly until it flowered into another delicate blossom of
verse. The situation was full of enjoyment while it lasted; and when
the seven years were over, Lady Dorothy married Henry, Lord
Spencer, who never wrote any poetry at all; while her lover said his
last good-bye in the most sparkling and heart-whole letter ever
penned by inconstant man. What would the author of “The Girdle,”
and “Go, Lovely Rose,” have thought of Browning’s uneasy rapture?
O lyric love, half angel and half bird,
And all a wonder and a wild desire.

He would probably have pointed out the exaggeration of the


sentiment, and the corresponding looseness of the lines. He would
certainly have agreed with the verdict of M. Sévelinges, had that
acute critic uttered it in his day. “It is well,” says M. Sévelinges, “that
passionate love is rare. Its principal effect is to detach men from all
their surroundings, to isolate them, to render them independent of
the relations which they have not formed for themselves; and a
civilized society composed of lovers would return infallibly to misery
and barbarism.”
Here is the French point of view, expressed with that lucidity
which the nation so highly esteems. Who shall gainsay its
correctness? But the Saxon, like the Teuton, is sentimental to his
heart’s core, and finds some illusions better worth cherishing than
truth. It was an Englishman, and one to whom the epithet “cynical”
has been applied oftenest, and with least accuracy, who wrote,—

When he was young as you are young,


When he was young, and lutes were strung,
And love-lamps in the casement hung.
THE SPINSTER
The most ordinarie cause of a single life is liberty, especially
in certain self-pleasing and humorous minds, which are so
sensible of every restriction, as they wil goe neere to thinke their
girdles and garters to be bonds and shakles.—Bacon.

In the Zend-Avesta, as translated by Anquetil-Duperron, there is a


discouraging sentence passed upon voluntary spinsterhood: “The
damsel who, having reached the age of eighteen, shall refuse to
marry, must remain in Hell until the earth is shattered.”
This assurance is interesting, less because of its provision for the
spinster’s future than because it takes into consideration the
possibility of her refusing to marry;—a possibility which slipped out
of men’s minds from the time of Zoroaster until our present day. A
vast deal has been written about marriage in the interval; but it all
bears the imprint of the masculine intellect, reasoning from the
masculine point of view, for the benefit of masculinity, and ignoring
in the most natural manner the woman’s side of life. The trend of
argument is mainly in one direction. While a few cynics gibe at love
and conjugal felicity, the mass of poets and philosophers unite in
extolling wedlock. Some praise its pleasures, others its duties, and
others again merely point out with Euripides that, as children cannot
be bought with gold or silver, there is no way of acquiring these
coveted possessions save by the help of women. Now and then a
rare word of sympathy is flung to the wife, as in those touching lines
of Sophocles upon the young girls sold in their “gleeful maidenhood”
to sad or shameful marriage-beds. But the important thing to be
achieved is the welfare and happiness of men. The welfare and
happiness of women are supposed—not without reason—to follow as
a necessary sequence; but this is a point which excites no very deep
concern.
Catholic Christendom throughout the Middle Ages, and long
afterwards, offered one practical solution to the problem of unmated
and unprotected womanhood,—the convent. The girl robbed of all
hope of marriage by bitter stress of war or poverty, the girl who
feared too deeply the turmoil and violence of the world, found
shelter in the convent. Within its walls she was reasonably safe, and
her vows lent dignity to her maidenhood. Bride of the Church, she
did not rank as a spinster, and her position had the advantage of
being accurately defined; she was part of a recognized social and
ecclesiastical system. No one feels this more solidly than does a nun
to-day, and no one looks with more contempt upon unmarried
women in the world. In her eyes there are but two vocations,—
wifehood and consecrated virginity. She perceives that the wife and
the religious are transmitters of the world’s traditions; while the
spinster is an anomaly, with no inherited background to give repute
and distinction to her rôle.
This point of view is the basis of much criticism, and has
afforded scope for the ridicule of the satirist, and for the outpourings
of the sentimentalist. A great many brutal jests have been flung at
the old maid, and floods of sickly sentiment have been wasted on
her behalf. She has been laughed at frankly as one rejected by men,
and she has been wept over as a wasted force, withering patiently
under the blight of this rejection. “Envy, hatred, malice, and all
uncharitableness” have been ascribed to her on one side, and a host
of low-spirited and treacly virtues, on the other. The spinster of
comedy is a familiar figure. A perfectly simple and ingenuous
example is the maiden aunt in “Pickwick,” Miss Rachel Wardle, whom
Mr. Tupman loves, and with whom Mr. Jingle elopes. She is spiteful
and foolish, envious of youth and easy to dupe. She is utterly
ridiculous, and a fair mark for laughter. She is pinched, and
withered, and hopelessly removed from all charm of womanhood;
and—it may be mentioned parenthetically—she is fifty years old. We
have her brother’s word for it.
There is nothing in this straightforward caricature that could, or
that should, wound anybody’s sensibilities. The fun is of a robust
order; the ridicule has no subtlety and no sting. But the old maid of
the sentimentalists, a creature stricken at heart, though
maddeningly serene and impossibly unselfish, is every bit as remote
from reality, and far less cheerful to contemplate. What can be more
offensive than the tearful plea for consideration put forward by her
apologists, who, after all, tolerate her only because, having no
career of her own, she is expected to efface herself in the interests
of other people. “The peculiar womanly virtues,” says a recent writer
upon this fruitful theme, “the power of self-sacrifice, warm
sympathies, compassion, patient endurance, represent an untold
amount of suffering on the part of the weaker sex in past ages. It is
to the world’s advantage that the fruit of such suffering be not lost.”
Here is a sparkling view of life; here is a joyous standpoint of
observation. There is generosity enough in the world to win for the
dejected, the wistful, the pathetic woman a fair share of
commiseration; provided always that she does not oppose her own
interests to the interests of those around her. But what if she
honestly prefers her own interests,—a not uncommon attitude of
mind? What if patient endurance be the very last virtue to which she
can lay claim? What if she is not in the least wistful, and never casts
longing looks at her sister-in-law’s babies, nor strains them
passionately to her heart, nor deems it a privilege to nurse her
nephews through whooping-cough and measles, nor offers herself in
any fashion as a holocaust upon other people’s domestic altars?
What if, holding her life in her two hands, and knowing it to be her
only real possession, she disposes of it in the way she feels will give
her most content, swimming smoothly in the stream of her own
nature, and clearly aware that happiness lies in the development of
her individual tastes and acquirements? Such a woman may, as Mr.
Brownell says, exhibit transparently “her native and elemental
inconsistencies;” but she calls for no commiseration, and perhaps
adds a trifle to the harmonious gayety of earth.
That she should be censured for laying claim to what is truly
hers seems unkind and irrational,—a tyranny of opinion. Marriage is
a delightful thing; but it is not, and never can be, a duty; nor is it as
a duty that men and women have hitherto zealously practised it. The
outcry against celibacy as a “great social disease” is louder than the
situation warrants. It is the echo of an older protest against the
deferring of the inevitable wedding-day; against the perverse
“boggling at every object,” which Burton found so exasperating a
trait in youth, and which La Bruyère calmly and conclusively
condemns. “There is,” says the French moralist, “a time when even
the richest women ought to marry. They cannot allow their youthful
chances to escape them, without the risk of a long repentance. The
importance of their reputed wealth seems to diminish with their
beauty. A young woman, on the contrary, has everything in her
favour; and if, added to youth, she possesses other advantages, she
is so much the more desirable.”
This is the simplest possible exposition of the masculine point of
view. It is plain that nothing is farther from La Bruyère’s mind than
the possibility of a lifelong spinsterhood for even the most
procrastinating heiress. He merely points out that it would be more
reasonable in her to permit a husband to enjoy her youth and her
wealth simultaneously. The modern moralist argues with less suavity
that the rich woman who remains unmarried because she relishes
the wide and joyous activity fostered by her independence is a
transgressor against social laws. She sins through dire selfishness,
and her punishment is the loss of all that gives dignity and
importance to her life. Only a few months ago a strenuous advocate
of matrimony—as if matrimony had need of advocates—pointed out
judicially in “Harper’s Magazine” that the childless woman has
nothing to show for all the strength and skill she has put into the
business of living. She may be intelligent, stimulating, and serene.
She may have seen much of the world, and have taken its lessons to
heart. She may have filled her days with useful and agreeable
occupations. Nevertheless, he considers her existence “in the long
run, a bootless sort of errand;” doubting whether she has acquired
anything that can make life more interesting to her at thirty-five, at
forty-five, at seventy. “And so much the worse for her.”
This is assuming that there are no interests outside of marriage;
no emotions, ambitions, nor obligations unconnected with the
rearing of children. We are invited to believe that the great world,
filled to its brim with pleasures and pains, duties, diversions, and
responsibilities, cannot keep a woman going—even to thirty-five—
without the incentive of maternity. Accustomed as we are to the
expansive utterances of conjugal felicity, this seems a trifle
overbearing. Charles Lamb thought it hard to be asked by a newly
wedded lady how—being a bachelor—he could assume to know
anything about the breeding of oysters. To-day the expressed doubt
is how—being spinsters or bachelors—we can assume to know
anything about the serious significance of life.
It is not the rich and presumably self-indulgent woman alone
who is admonished to mend her ways and marry. The sentence
extends to the working classes, who are held to be much in fault.
Even the factory girl, toiling for her daily bread, has been made the
subject of censure as unjust as it is severe. What if she does covet
the few poor luxuries,—the neat shoes and pretty frock which
represent her share of æsthetic development? What if she does
enjoy her independence, and the power to spend as she pleases the
money for which she works so hard? These things are her
inalienable rights. To limit them is tyranny. To denounce them is
injustice. We may sincerely believe that she would be better and
happier if she married; and that the bringing up of children on the
precarious earnings of a working-man would be a more legitimate
field for her intelligence and industry. But it is her privilege to decide
this point for herself; and no one is warranted in questioning her
decision. She does not owe matrimony to the world.
There is still another class of women whose spinsterhood is
hardly a matter of choice, yet whose independence has aroused
especial criticism and denunciation. A few years ago there appeared
in “Macmillan’s Magazine” a well-written article on the educated,
unmarried, and self-supporting women, who, in London alone, fill
countless clerical, official, and academic positions. It was pointed out
that these toilers, debarred by poverty from agreeable social
conditions, lead lives of cheerful and honourable frugality, preserving
their self-respect, seeking help and commiseration from none,
enjoying their scanty pleasures with intelligence, and doing their
share of work with eager and anxious precision. Surely if any
creatures on God’s earth merit some esteem, these spinsters may be
held in deference. Yet the writer of the article unhesitatingly, though
not unkindly, summed up the case against them. No woman with a
sensitive conscience, he avowed, can be happy on such terms. “She
more than suspects she is in danger of serious moral deterioration....
She is aware that her mode of life is essentially selfish, and therefore
stands condemned.”
In the name of Heaven, why? Would her mode of life be less
selfish if she asked a support from a married brother, or a wealthy
aunt? Is it necessary to her moral well-being that she should pass
her days in polite servitude? Apparently it is; for hardly had the
“Macmillan” article appeared, when a more strenuous critic in the
“Spectator” took its writer severely to task, not for his censorship,
but for his leniency. The “Spectator” declared in round terms that
the woman who devotes herself to the difficult problem of her own
support “lives a more or less unnatural life of self-dependence;—the
degree of the unnaturalness depending on the degree of her self-
dependence, and the completeness of the disappearance of that
religious devoutness which prevents loneliness from degenerating
into self-dependence.”
Shades of Addison and Steele pardon this cumbrous sentence!
That self-dependence might degenerate into loneliness we can
understand; but how or why should loneliness degenerate into self-
dependence, and what has either loneliness or self-dependence to
do with the “disappearance of religious devoutness”? Is religion also
a perquisite of family life? May we not be devout in solitude? “Be
able to be alone,” counsels Sir Thomas Browne, whose piety was of
a most satisfying order. It is not profane to plan or to advance an
individual career. We do not insult Providence by endeavouring to
provide for ourselves. And if the restlessness of modern life impels
women of independent fortune to enter congenial fields of work, the
freedom to do this thing is their birthright and prerogative. We can
no more sweep back the rising tide of interests and ambitions than
we can sweep back the waves of the Atlantic. A hundred years ago,
marriage was for an intelligent woman a necessary entrance into life,
a legitimate method of carrying out her ideas and her aims. To-day
she tries to carry them out, whether she be married or not. Perhaps
some awkwardness of self-assertion disfigures that “polished
moderation” which is her highest grace; but the frank resoluteness
of her attitude is more agreeable to contemplate than sad passivity
and endurance. Mr. John Stuart Mill said that a woman’s inheritance
of “subjection”—he never minced words—induced, on the one hand,
a capacity for self-sacrifice, and, on the other, a habit of
pusillanimity. Both characteristics have been modified by changing
circumstances. But with more courage and less self-immolation has
come a happier outlook upon life, and an energy which is not always
misplaced. Mariana no longer waits tearfully in the Moated Grange.
She leaves it as quickly as possible for some more healthful
habitation, and a more engaging pursuit.
There is one English author who has defended with delicacy that
sagacious self-respect which, even in his time, preserved a woman
now and then from the blunder of an unequal and unbecoming
marriage. De Quincey, extolling the art of letter-writing, pays this
curious bit of homage to his most valued correspondents:—
“Three out of four letters in the mail-bag will be written by that
class of women who have the most leisure, and the most interest in
a correspondence by the post; and who combine more intelligence,
cultivation, and thoughtfulness than any other class in Europe. They
are the unmarried women over twenty-five, who, from mere dignity
of character, have renounced all prospects of conjugal and parental
life, rather than descend into habits unsuitable to their birth. Women
capable of such sacrifices, and marked by such strength of mind,
may be expected to think with deep feeling, and to express
themselves (unless when they have been too much biassed by
bookish connections) with natural grace.”
This is something very different from the “All for Love, and the
World well lost,” flaunted by novelists and poets; very different from
the well-worn “Quand on n’a pas ce qu’on aime, il faut aimer ce
qu’on a,” which has married generations of women. But in the
philosophy of life, the power to estimate and to balance scores
heavily for success. It is not an easy thing to be happy. It takes all
the brains, and all the soul, and all the goodness we possess. We
may fail of our happiness, strive we ever so bravely; but we are less
likely to fail if we measure with judgment our chances and our
capabilities. To glorify spinsterhood is as ridiculous as to decry it.
Intelligent women marry or remain single, because in married or in
single life they see their way more clearly to content. They do not, in
either case, quarrel with fate which has modelled them for, and
fitted them into, one groove rather than another; but follow,
consciously or unconsciously, the noble maxim of Marcus Aurelius:
“Love that only which the gods send thee, and which is spun with
the thread of thy destiny.”
THE TOURIST

See Thrale’s grey widow with a satchel roam,


And bring in pomp laborious nothings home.
The Baviad.

“Potter hates Potter, and Poet hates Poet,”—so runs the wisdom of
the ancients,—but tourist hates tourist with a cordial Christian
animosity that casts all Pagan prejudices in the shade. At home we
tolerate—sometimes we even love—our fellow creatures. We can see
large masses of them in church and theatre, we can be jostled by
them in streets, and be kept waiting by them in shops, and be
inconvenienced by them at almost every turn, without rancorous
annoyance or ill will. But abroad it is our habit to regard all other
travellers in the light of personal and unpardonable grievances. They
are intruders into our chosen realms of pleasure, they jar upon our
sensibilities, they lessen our meagre share of comforts, they are
everywhere in our way, they are always an unnecessary feature in
the landscape.
I love not man the less, but nature more,
wrote Byron, when sore beset; but the remark cannot be said to
bear the stamp of truth. Nine tenths of the poet’s love for nature
was irritation at the boundless injustice and the sterling stupidity of
man. He would never have expressed so much general benevolence
had Europe in his time been the tourist-trodden platform it is to-day.
We might, were we disposed to be reasonable, bear in mind the
humiliating fact that we too are aliens, out of harmony with our
surroundings, and marring, as far as in us lies, the charm of ancient
street or the still mountain side. Few of us, however, are so candid
as Mr. Henry James, who, while detesting his fellow travellers,
frankly admits his own inherent undesirability. “We complain,” he
says, “of a hackneyed and cockneyized Europe; but wherever, in
desperate search of the untrodden, we carry our much-labelled
luggage, our bad French, our demand for a sitzbath and pale ale, we
rub off the bloom of local colour, and establish a precedent for
unlimited intrusion.”
This is generous, and it is not a common point of view.
“Americans do roam so,” I heard an Englishwoman remark
discontentedly in Cook’s Paris office, where she was waiting with
manifest impatience while the clerk made up tickets for a party of
trans-Atlantic kindred. It never seemed to occur to her that she was
not upon her own native heath. The habit of classifying our distastes
proves how strong is our general sense of injury. We dislike English
tourists more than French, or French more than English, or
Americans more than either, or Germans most of all,—the last a
common verdict. There is a power of universal mastery about the
travelling Teuton which affronts our feebler souls. We cannot cope
with him; we stand defeated at every turn by his resistless
determination to secure the best. The windows of the railway
carriages, the little sunny tables in the hotel dining-rooms, the back
seats—commanding the view—of the Swiss funiculaires;—all these
strong positions he occupies at once with the strategical genius of a
great military nation. No weak concern for other people’s comfort
mars the simple straightforwardness of his plans, nor interferes with
their prompt and masterly execution. Amid the confusion and misery
of French and Italian railway stations, he plays a conqueror’s part,
commanding the services of the porters, and marching off
triumphantly with his innumerable pieces of hand luggage, while his
fellow tourists clamour helplessly for aid. “The Germans are a rude,
unmannered race, but active and expert where their personal
advantages are concerned,” wrote the observant Froissart many
years ago. He could say neither more nor less were he travelling
over the Continent to-day.
Granted that the scurrying crowds who infest Italy every spring,
and Switzerland every summer, are seldom “children of light;” that
their motives in coming are, for the most part, unintelligible, and
their behaviour the reverse of urbane;—even then there seems to be
no real cause for the demoralization that follows in their wake, for
the sudden and bitter change that comes over a land when once the
stranger claims it as his own. It is the cordial effort made to meet
the tourist halfway, to minister to his supposed wants, and to profit
by his supposed wealth, that desolates the loveliest cities in the
world, that flouts the face of nature, and rasps our most tender
sensibilities. Venice turned into a grand bazaar, Vaucluse packed with
stalls for the sale of every object which ought never to be found
there, the Falls of the Rhine lit up by electricity, like the
transformation scene of a ballet;—is it our misfortune or our fault
that these things may be directly traceable to us? Do we like to see
a trolley-car bumping its way to Chillon, or to find the castle
entrance stocked with silver spoons, and wooden bears, and
miniature Swiss châlets? Shall I confess that I watched a youthful
countrywoman of my own carrying delightedly away—as an
appropriate souvenir of the spot—a group consisting of Mother bear
sitting up languidly in bed, Nurse bear wrapping Infant bear in
swaddling-cloths, and Doctor bear holding a labelled bottle of
medicine? There seemed a certain incongruity about the purchase,
and a certain lack of sensibility in the purchaser. Chillon is not
without sombre associations, nor poetic life; and if Byron’s “Prisoner”
no longer wrings our hearts, still youth is youth,—or, at least, it used
to be,—and the
seven columns, massy and grey,
were at one time part of its inheritance. Is it better, I wonder, to
begin life with a few illusions, a little glow, a pardonable capacity for
enthusiasm, or to be so healthily free from every breath of
sentiment as to be capable—at eighteen—of buying comic bears
within the melancholy portals of Chillon.
Travelling, like novel-writing, is but a modern form of activity;
and tourists, like novelists, are increasing at so fearful a rate of
speed that foreign countries and library shelves bid fair to be equally
overrun. There was a time when good men looked askance both
upon the page of fable, and upon those far countries where reality
was stranger than romance. “I was once in Italy myself,” confesses
the pious Roger Ascham; “but I thank God my abode there was but
nine days.” Nine days seem a scant allowance for Italy. Even the
business-like traveller who now scampers “more Americano” over
Europe is wont to deal more generously with this, its fairest land.
But in Roger Ascham’s time nine days would hardly have permitted a
glimpse at the wonders from which he so swiftly and fearfully
withdrew.
Now and then, as years went by, men with a genuine love of
roving and adventure wandered far afield, unbaffled by difficulties,
and unscandalized by foreign creeds and customs. James Howell,
that most delightful of gossips and chroniclers, has so much to say
in praise of “the sweetness and advantage of travel,” that even now
his letters—nearly three hundred years old—stir in our hearts the
wayfarer’s restless longing. After being “toss’d from shore to shore
for thirty-odd months,” he can still write stoutly: “And tho’ these
frequent removes and tumblings under climes of differing temper
were not without some danger, yet the delight which accompany’d
them was far greater; and it is impossible for any man to conceive
the true pleasure of peregrination, but he who actually enjoys and
puts it into practice.” Moreover, he is well assured that travel is “a
profitable school, a running academy, and nothing conduceth more
to the building up and perfecting of a man. They that traverse the
world up and down have the clearest understanding; being faithful
eye-witnesses of those things which others receive but in trust,
whereunto they must yield an intuitive consent, and a kind of implicit
faith.”
In one respect, however, Howell was a true son of his day, of the
day when Prelacy and Puritanism alternately afflicted England. For
foreign cities and foreign citizens he had a keen and intelligent
appreciation; nothing daunted his purpose, nor escaped his
observation; but he drew the line consistently at the charms of
nature. The “high and hideous Alps” were as abhorrent to his soul as
they were, a century later, to Horace Walpole’s. It was the gradual—I
had almost said the regrettable—discovery of beauty in these
“uncouth, huge, monstrous excrescences” which gave a new and
powerful impetus to travel. Here at least were innocent objects of
pilgrimage, wonders uncontaminated by the evils which were
vaguely supposed to lurk in the hearts of Paris and of Rome. It was
many, many years after Roger Ascham’s praiseworthy flight from
Italy that we find Patty More, sister to the ever-virtuous Hannah,
writing apprehensively to a friend:—
“What is to become of us? All the world, as it seems, flying off to
France, that land of deep corruption and wickedness, made hotter in
sin by this long and dreadful Revolution. The very curates in our
neighbourhood have been. I fear a deterioration in the English
character is taking place. The Ambassador’s lady in Paris could not
introduce the English ladies till they had covered up their bodies.”
This sounds rather as though England were corrupting France.
Perhaps, notwithstanding the truly reprehensible conduct of the
curates,—for whom no excuse can be made,—the exodus was not so
universal as the agitated Mrs. Patty seemed to think. There were still
plenty of stay-at-homes, lapped in rural virtues, and safe from
contamination;—like the squire who told Jane Austen’s father that he
and his wife had been quarrelling the night before as to whether
Paris were in France, or France in Paris. The “Roman Priest
Conversion Branch Tract Society” gave to bucolic Britain all the
Continental details it required.
But when the “hideous Alps” became the “matchless heights,”
the “palaces of Nature,” when poets had sung their praises lustily,
and it had dawned upon the minds of unpoetic men that they were
not merely obstacles to be crossed, but objects to be looked at and
admired;—then were gathered slowly the advance guards of that
mighty army of sight-seers which sweeps over Europe to-day.
“Switzerland,” writes Mr. James gloomily, “has become a show
country. I think so more and more every time I come here. Its use in
the world is to reassure persons of a benevolent imagination who
wish the majority of mankind had only a little more elevating
amusement. Here is amusement for a thousand years, and as
elevating certainly as mountains five miles high can make it. I expect
to live to see the summit of Mount Rosa heated by steam-tubes, and
adorned with a hotel setting three dinners a day.”
The last words carry a world of weight. They are the key-note of
the situation. Tourists in these years of grace need a vast deal of
food and drink to keep their enthusiasm warm. James Howell lived
contentedly upon bread and grapes for three long months in Spain.
Byron wrote mockingly from Lisbon: “Comfort must not be expected
by folks that go a-pleasuring;” and no one ever bore manifold
discomforts with more endurance and gayety than he did. But now
that the “grand tour”—once the experience of a lifetime—has
become a succession of little tours, undertaken every year or two,
things are made easy for slackened sinews and impaired digestions.
The average traveller concentrates his attention sternly upon the
slowness of the Italian trains, the shortness of the Swiss beds, the
surliness of the German officials, the dirt of the French inns, the
debatableness of the Spanish butter, the universal and world-
embracing badness of the tea. These things form the staple topics of
discussion among men and women who exchange confidences at
the table d’hôte, and they lend a somewhat depressing tone to the
conversation, which is not greatly enlivened by a few side remarks
connecting the drinking water with the germs of typhoid fever. It is
possible that the talkers have enjoyed some exhilarating
experiences, some agreeable sensations, which they hesitate—
mistakenly—to reveal; but they wax eloquent on the subject of cost.
“The continual attention to pecuniary disbursements detracts terribly
from the pleasure of all travelling schemes,” wrote Shelley in a
moment of dejection; and the sentiment, couched in less Johnsonian
English, is monotonously familiar to-day. Paying for things is a great
trouble and a great expense; and the tourist’s uneasy apprehension
that he is being overcharged turns this ordinary process—which is
not wholly unknown at home—into a bitter grievance. To hear him
expatiate upon the subject, one might imagine that his fellow
creatures had heretofore supplied all his wants for love.
Great Britain had sent her restless children out to see the world
for many years before faraway America joined in the sport, while the
overwhelming increase of German travellers dates only from the
Franco-Prussian War. Now the three armies of occupation march and
countermarch over the Continent, very much in one another’s way,
and deeply resentful of one another’s intrusion. “The English”—again
I venture to quote Froissart—“are affable to no other nation than
their own.” The Americans—so other Americans piteously lament—
are noisy, self-assertive, and contemptuous. The fault of the
Germans, as Canning said of the Dutch,—
Is giving too little and asking too much.
All these unlovely characteristics are stimulated and kept well to the
fore by travel. It is only in our fellow tourists that we can recognize
their enormity. When Mr. Arnold said that Shakespeare and Virgil
would have found the Pilgrim Fathers “intolerable company,” he was
probably thinking of poets and pietists shut up together in fair
weather and in foul, while the little Mayflower pitched its slow way
across the “estranging sea.”
It requires a good deal of courage to quote Lord Chesterfield
seriously in these years of grace. His reasonableness is out of favour
with moralists, and sentimentalists, and earnest thinkers generally.
But we might find it helpful now and then, were we not too wrapped
in self-esteem to be so easily helped. “Good breeding,” he says
thoughtfully, “is a combination of much sense, some good nature,
and a little self-denial for the sake of others, with a view to obtain
the same indulgence from them.” Here is a “Tourist’s Guide,”—the
briefest ever penned. We cannot learn to love other tourists,—the
laws of nature forbid it,—but, meditating soberly on the impossibility
of their loving us, we may reach some common platform of
tolerance, some common exchange of recognition and amenity.
THE HEADSMAN
Et cependant, toute grandeur, toute puissance, toute
subordination repose sur l’exécuteur: il est l’horreur et le lien de
l’association humaine. Otez du monde cet agent
incompréhensible; dans l’instant même l’ordre fait place au
chaos, les trônes s’abîment, et la société disparaît.
Joseph de Maistre.

What a sombre and striking figure in the deeply coloured background


of history is the headsman, that passive agent of strange tyrannies,
that masked executor of laws which were often but the expression
of man’s violence! He stands aloof from the brilliant web of life, yet,
turn where we will, his shadow falls across the scene. In the little
walled towns of mediæval Europe, in the splendid cities, in the broad
lands held by feudal lord or stately monastery, wherever the struggle
for freedom and power was sharpest and sternest, the headsman
played his part. An unreasoning and richly imaginative fear wrapped
him in a mantle of romance, as deeply stained as the scarlet cloak
which was his badge of office. Banished from the cheerful society of
men (de Maistre tells us that if other houses surrounded his abode,
they were deserted, and left to crumble and decay), he enjoyed
privileges that compensated him for his isolation. His tithes were
exacted as ruthlessly as were those of prince or baron; and if his
wife chattered little on summer days with friendly gossips, she was
sought in secret after nightfall for hideous amulets that blessed—or
cursed—the wearer. From father to son, from son to grandson, the
right was handed down; and the young boy was taught to lift and
swing the heavy sword, that his hand might be as sure as his eye,
his muscles as hard as his heart.
Much of life’s brilliant panorama was seen from the elevation of
the scaffold in the days when men had no chance nor leisure to die
lingeringly in their beds. They fell fighting, or by the assassin’s hand,
or by the help of what was then termed law; and the headsman,
standing ever ready for his rôle, beheld human nature in its worst
and noblest aspects, in moments of stern endurance and supreme
emotion, of heroic ecstasy and blank despair. Had he a turn for the
marvellous, it was gratified. He saw Saint Denis arise and carry his
severed head from Montmartre to the site of the church which bears
his name to-day. He saw Saint Felix and Saint Alban repeat the
miracle. He heard Lucretia of Ancona pronounce the sacred name
three times after decapitation. Ordericus Vitalis, that most engaging
of historians, tells us the story of the fair Lucretia; and also of the
Count de Galles, who asked upon the scaffold for time in which to
say his Pater Noster. When he reached the words, Et ne nos inducas
in tentationem, the headsman—all unworthy of his office—grew
impatient, and brought down his shining sword. The Count’s head
rolled on the ground, but from his open lips came with terrible
distinctness the final supplication, Sed libera nos a malo.
These were not trivial experiences. What a tale to tell o’ nights
was that of Théodoric Schawembourg, whose headless trunk arose
and walked thirty paces from the block! Auberive, who has
preserved this famous legend, embroiders it with so many fantastic
details that the salient point of the narrative is well-nigh lost; but the
dead and forgotten headsman beheld the deed in all its crude
simplicity. Had he, on the other hand, a taste for experimental
science, it was given him to watch the surgeons of Prague, who in
1679 replaced a severed head upon a young criminal’s shoulders,
and kept the lad alive for half an hour. Panurge, it will be
remembered, was permanently successful in a similar operation; but
Panurge was a man of genius. We should hardly expect to find his
like among the doctors of Prague.
Strange and unreasonable laws guaranteed to the headsman his
full share of emoluments. He was well paid for his work, and never
suffered from a dull season. From the towns he received poultry and

You might also like