Multiparadigm Programming Using C 1st Edition Dirk Vermeir instant download
Multiparadigm Programming Using C 1st Edition Dirk Vermeir instant download
https://ebookbell.com/product/multiparadigm-programming-
using-c-1st-edition-dirk-vermeir-48803382
https://ebookbell.com/product/multiparadigm-programming-in-mozartoz-
second-international-conference-moz-2004-charleroi-belgium-
october-78-2004-revised-selected-and-invited-papers-1st-edition-gert-
smolka-auth-4604406
https://ebookbell.com/product/multiparadigm-constraint-programming-
languages-1st-edition-petra-hofstedt-auth-2448792
https://ebookbell.com/product/multiparadigm-constraint-programming-
languages-1st-edition-petra-hofstedt-auth-4104716
https://ebookbell.com/product/multiparadigm-modelling-approaches-for-
cyberphysical-systems-1st-edition-bedir-tekinerdogan-editor-34708930
Foundations Of Multiparadigm Modelling For Cyberphysical Systems Paulo
Carreira Vasco Amaral Hans Vangheluwe Carreira
https://ebookbell.com/product/foundations-of-multiparadigm-modelling-
for-cyberphysical-systems-paulo-carreira-vasco-amaral-hans-vangheluwe-
carreira-28689244
https://ebookbell.com/product/introduction-to-the-design-and-analysis-
of-algorithms-a-multiparadigm-approach-1st-edition-arthur-
nunes-50244506
https://ebookbell.com/product/kotlin-indepth-volii-a-comprehensive-
guide-to-modern-multiparadigm-language-aleksei-sedunov-44848948
https://ebookbell.com/product/kotlin-indepth-voli-a-comprehensive-
guide-to-modern-multiparadigm-language-aleksei-sedunov-44848972
https://ebookbell.com/product/kotlin-indepth-vol-i-a-comprehensive-
guide-to-modern-multiparadigm-language-aleksei-sedunov-44859406
Multi-Paradigm Programming using c++
Springer-Verlag London Ltd.
Dirk Vermeir
Multi-Paradigm
Programming
using c++
Springer
Dirk Vermeir, PhD
Department of Computer Science, Free University of Brussels,
VUB, Pleinlaan 2, B1050 Brussels, Belgium
Apart from any fair dealing for the purposes of research or private study, or criticism or review, as
permitted under the Copyright, Designs and Patents Act 1988, this publication may only be reproduced,
stored or transmitted, in any form or by any means, with the prior permission in writing of the publishers,
or in the case of reprographic reproduction in accordance with the terms of licences issued by the
Copyright Licensing Agency. Enquiries concerning reproduction outside those terms should be sent to
the publishers.
ISBN 978-1-85233-483-3 ISBN 978-1-4471-0311-0 (eBook)
DOI 10.1007/978-1-4471-0311-0
http://www.springer.co.uk
© Springer-Verlag London 2001
Originally published by Springer-Verlag London Berlin Heide1berg in 2001
The use of registered names, trademarks etc. in this publication does not imply, even in the absence of a
specific statement, that such names are exempt from the relevant laws and regulations and therefore free
for general use.
The publisher makes no representation, express or implied, with regard to the accuracy of the
information contained in this book and cannot accept any legal responsibility or liability for anyerrors or
omissions that may be made.
Many Computer Science programmes teach two programming languages in the first
years of the core curriculum. The first language is selected for its simple semantics
and ease of use so that students can learn about fundamental computing topics such
as control structures, functions, recursion, abstract data types, etc. without bothering
about the underlying hardware and operating system aspects. C++ is not a good lan-
guage for this purpose.
The second language is then chosen to complement the first in that its teaching pro-
vides an opportunity to study the aspects that are abstracted from in the first language:
efficiency, run-time support including operating system interfaces and memory man-
agement, compilation and linking, etc. Choosing an industrially relevant and wide-
spectrum language has obvious additional advantages. C++ is an ideal candidate for
this purpose as it exposes the student to all of the above aspects while at the same time
it provides powerful abstraction mechanisms supporting generic and object-oriented
programming.
This textbook presents a concise yet reasonably complete introduction to the C++
programming language and its abstraction mechanisms. The reader is expected to be
familiar with basic programming concepts, making this book suitable, for example,
for second year computer science students.
C++ is a wide spectrum language that provides a confusing number of features, which
I've tried to streamline by providing a hierarchy of concepts centred around the no-
tions of types and type constructors. The structure of the book reflects the gradual
introduction of these concepts:
v
vi PREFACE
Each time, examples are provided to motivate the inclusion of a feature into the lan-
guage.
The text also touches on the implementation of the various concepts. This is necessary
to motivate the decisions that have influenced the design of C++, thus making it easier
to really understand the language. Moreover, knowing a bit about the implementation
is also useful when assessing the efficiency aspects of alternative designs.
Chapter Summary
• Chapter 1 presents the basic concepts of C++: data objects, values, types and
variables, references, object construction, functions; basic lexical and syntactic
(scope, namespaces) aspects of the language; compilation and linking.
• Chapter 2 covers built-in types and associated operators; it also introduces con-
versions and operator overloading.
• Functions are covered in Chapter 3: control flow, local and static data objects,
overloading.
• Pointers, constant objects and arrays are presented as built-in type constructors
(i.e. functions that map types to types) in Chapter 5. A taxonomy of object
memory management alternatives is also presented.
• Chapter 10 presents the iostream library, including its design and how to imple-
ment new stream classes.
Supplementary Materials
The programs from the book, as well as other illustrative programs and case studies
can be found on the web site
http://tinf2.vub.ac.be/cpp/index.html.
Acknowledgements
This book was greatly improved through the comments and suggestions of students
and colleagues who read preliminary versions: Marina De Vos, Koen De Winter, Stijn
Heymans, Viviane lonckers, Carine Lucas, Michael Peeters, Frank Tavernier, Dirk
Verdonck, Wei Wang. Any mistakes that remain are of course my own.
Contents
Preface v
ix
x CONTENTS
2 Built-in Types 25
2.1 Arithmetic Types 25
2.2 Conversions for Arithmetic Types 27
2.3 Arithmetic Type Operations. 28
2.4 String Literals . 32
3 Functions 37
3.1 Function Declarations . ....... 37
3.1.1 Function Types, Signatures . 37
3.1.2 Default Arguments . . . . . 38
3.1.3 Unspecified Number of Arguments 38
3.1.4 Inline Functions 39
3.2 Overloading . . . . . 41
3.3 Function Definitions 42
3.3.1 Statements . 42
3.3.2 Control Flow Statements 43
The compound statement and the sequence operator 43
The if statement and the ? operator 43
The while statements 44
The £or statement . . 45
The switch statement . 46
The return, break and continue statements . 47
3.3.3 Local and Static Variables 49
Local object lifetime . 49
Persistent local objects 49
4 User-Defined Types 51
4.1 Abstract Data Types . 51
4.2 Classes ...... . 53
4.2.1 Class Members, Access Specification 53
4.2.2 Class Objects . . . . . . . . . . . . . 54
4.2.3 Data Member Declarations and Object Layout 54
4.2.4 Class Scope . . . . . . . . . . . 55
4.2.5 Function Member Declaration . 55
4.2.6 Overloading Member Functions 56
4.2.7 Initializing a Class Object . . . 56
CONTENTS Xl
9 Exceptions 205
9.1 Throwing and Catching Exceptions. 205
9.2 Run-Time Behaviour . . . . . . . . 208
9.3 Exceptions, Constructors and Destructors 210
9.3.1 Exceptions and Resource Management 210
9.3.2 Constructors Throwing Exceptions . 211
9.3.3 Destructors Throwing Exceptions 212
9.4 Exception Specifications 213
9.5 Standard Exceptions 214
10 Iostreams 217
10.1 Requirements 217
10.2 Design . . . . 218
10.3 Streambuf .. 219
10.4 Stream Base Classes 223
CONTENTS xv
Bibliography 273
Index 275
Chapter 1
In C++, data are kept in (data) objects where an object is simply an area of memory.
Since each memory location is associated with a unique address, we can use the ad-
dress of the first (in the order of the addresses) byte of the object as the address of the
whole object) . An object's size, i.e. the size of its memory area, is fixed for its lifetime
but the contents of the associated memory area can, in general, vary over time.
Figure 1.1 depicts an object of size 28 bytes with address 10002.
memory
00000
I,(10002value~ I10030 IFFFFF
,,
object
address
Figure 1.1: Object, address, value.
1We will see in Section 5.2 that C++ makes these addresses available to the programmer, i.e. they can
be manipulated as other values. This contrasts with other programming languages such as Scheme, Java,
Prolog that provide a higher level of abstraction which does not include the concept of address. Of course,
that does not mean that these languages do not use addresses internally (as a matter of fact e.g. Java uses
addresses more intensely than many C++ programs). It's just that the programmer does not have access to
them.
1
2 CHAPTER 1. BASIC CONCEPTS OF C++
to denote 5.
Simple values, i.e. values that belong to primitive data types such as integers, charac-
ters or literal strings, may be referenced directly using so-called constants. E.g.
23
denotes an integer value. Note that 23 is not an object, i.e. it does not have a known
address.
20f course, to properly support ADTs we also must be able to hide implementation details, but as will
be made clear in Chapter 4, C++ provides the necessary facilities for this as well.
3Templates are programmer-defined type constructors in C++, see Chapter 6.
4The otber ways are through references (see Section 1.3), pointers or arrays (see Chapter 5).
1.2. DEFINING AND MANIPULATING OBJECTS 3
Finally, we can denote values using expressions that compute new values using op-
erations that are applied on other values or objects. Variables and constants are also
considered to be (simple) expressions.
E.g. if x is a variable that refers to an integer object with value 5, then the expression
x+23
refers to the value 28. Here + is an operator representing integer addition. We will
see that some expressions refer to an object (and its value) while others result in a pure
value. The expression x+23 above represents a pure value.
In general, a reference to a value through an object (with this value) is called an lvalue
while a value without an address is called an rvalue 5 •
Thus the simple expression x denotes an lvalue while x+y denotes an rvalue.
I NameOfType NameOfVariable(InitialValue);
int x(5);
int y(x+7);
double z(3.14);
When processing this fragment, the compiler will reserve 16 bytes of memory: 4 bytes
for x, 4 bytes for y and 8 bytes for z. Moreover, where appropriate9, the compiler will
5The importance of the distinction will become clear in Section 1.2.
6 An alternative syntax is
memory
x y z
int int double
The assignment statement lO can be used to change the value of an object. Its syntax is
LeftExpression = RightExpression;
Here, LeftExpression on the left-hand side of the assignment operator "=" must yield
an lvalue while RightExpression may result in either an lvalue or an rvalue. The
effect of the assignment is that the contents of the object referred to by LeftExpression
becomes the value denoted by RightExpression 11.
E.g. at the end of the following fragment the value of y will be 29, as illustrated in
Figure 1.3.
int x(5);
int y(x+7);
double z(3.14);
y =y * 2 + x;
1.3 References
An alternative way to refer to an object is by using a reference variable or, more
correctly, a variable of a reference type.
Such a variable is defined using a statement of the form
memory (before)
x
5
y
12
z
3.14 I I
" I
t, ,
I ,
1 ~
Y =}
...
*2+ ~
_---
29
-
~~ memory (after)
5 3.14
x y z
iot iot double
Like a nonnal variable, the association between a reference variable and the object it
refers to is immutable and must be established when the variable is defined.
Note that "reference to a type" is a type constructor, i.e. for any type T, there exists a
type T&:.
As an example, in the fragment
int x(5);
int& y(x);
y = 6;
both y and x refer to the same object. Consequently, after the assignment to y, also
the value of x is 6.
Reference variables are usually implemented as shown in Figure 1.4 which illustrates
the above code fragment: the "real" value (which is unaccessible to the programmer)
of y is the address of the object referred to by x.
Reference variables may not appear to be very useful but they are important in com-
bination with parameter passing to functions (Section 1.4). In addition, they come in
handy to implement immutable relationships between class objects (Section 4.2.12,
page 67).
6 CHAPTER 1. BASIC CONCEPTS OF C++
memory
r [00031
x y
int int&
y=6
" "
""
memory
x
int
1.4 Functions
1.4.1 Defining a Function
Sometimes, an expression or, more generally, a sequence of statements, is needed
many times in a program. In order to avoid repeating the same code fragment again
and again, one may define a named junction that serves as an abstraction for the
behaviour of the code fragment.
A function can then be regarded as a black box that returns an output value, based on
its parameter input values (Figure 1.5).
xl
xn
___-=-:-----,:~( {unction ( J result" f(xl, ... ,xn)
parameters
int x(3);
int y(O) ;
int z(4);
y = x * x;
y=y+z*z;
1.4. FUNCTIONS 7
int
square(int a) {
return a*a;
}
ReturnType
FunctionNarne(PararneterDeclarationList) {
StatementList
}
• The name of the type of the output (return) value (int in the example). It may
be that there is no return value, in which case the return type should be specified
as void.
return Expression;
where, of course, the type of Expres s ion must match the declared type ofthe
return value (if the return type was void, there should be no return statement).
FunctionNarne(PararneterExpressionList)
8 CHAPTER 1. BASIC CONCEPTS OF C++
int x(3);
int y(O);
int z(4);
int
square(int a) {
return a*a;
}
y = square(x) + square(z);
Thus, the evaluation of a function call starts by copying the actual parameter
values to fresh local parameter variables.
E.g. for a call f (e 1, e2) to a function R f (Ti vi, T2 v2), this boils
down to defining two local objects
Tl vl( el);
T2 v2( e2);
2. The statements of the function body are executed. This happens in an "environ-
ment" where the following names are available:
• local names, e.g. variables (including the ones containing copies of the
actual parameters, see (1) above
• all the names available in encompassing scopes 13 (see Section 1.7.1).
4. All memory allocated during the execution of the function call, e.g. to store the
parameter objects, is deallocated, i.e. returned to the operating system.
13 As long as there is no more closely nested (around the function body) scope that defines the same name.
1.4. FUNCTIONS 9
Thus a function call needs extra memory from the operating system to store "local"
information such as the formal parameter variable objects, (local) variables that are
defined within the body, etc. This extra memory area is called the function call's
frame 14.
Since function calls may be nested, i.e. one function may call another (or the same)
function from within its body, it follows that such memory is allocated and deallocated
in a "first-allocated-Iast-deallocated" fashion. Hence the system will manage a call
stack of frames corresponding to "active" function calls.
The process is illustrated in Figure 1.6 for the expression factorial (3) where the
function factorial is defined below.
int
factorial(int n) {
if (n<2)
return 1;
else
return n*factorial(n -1);
}
Here the function body consists of an if statement which, when executed, first tests the
condition expression n<2. If this is the case, i.e. if the value of the parameter variable
n is indeed strictly smaller than 2, then the return 1 statement is executed, return-
ing 1 for the function call. If the condition is false, i.e. the value of the parameter vari-
able n is at least 2, then the alternative statement return n * factorial (n-
1) is executed. Note that to compute the expression n * factorial (n-l), an-
other call to the factorial function (this time with a smaller parameter value) must be
performed.
return 1
",,",6
Figure 1.6 shows snapshots of the call stack at various stages of the evaluation of
factorial (3).
1. factorial (3) is being evaluated: since n=3, which is not smaller than
14 Actually, a frame contains more than parameters and local variable objects: also saved information on
the state of the CPU just before the call, including the program counter, is kept in the frame.
10 CHAPTER 1. BASIC CONCEPTS OF C++
2. factorial (2) is being evaluated: n is still not smaller than 2, so, again,
n*factorial (n-1) is evaluated, leading to a call to factorial (1).
int x(3);
int y(4);
void
swap(int& a,int& b) {
int tmp(a);
a =
b;
b = tmp;
}
swap(x,y);
Note that
• The function swap does not have a return type. Consequently, its body does
not contain a return statement.
• Within the function, an extra local int variable (and corresponding object) tmp
is defined. Hence the frame corresponding to a call to swap will contain three
variables: a, b (the formal parameter variables) and tmp.
1.4. FUNCTIONS 11
• The fonna1 parameter variables are both of type int&, i.e. they contain refer-
ences to integers.
According to the mechanism described in Section 1.4.2, the fonnal parameters a and
b will be initialized using the parameter expressions x and y, which, incidently, both
yield 1values. But we know from Section 1.3 that reference variables such as a and b
are defined by binding them to the same object as the initializing expression. Hence a
will refer to the same object as x and b will refer to the same object as y, as illustrated
in Figure 1.7 which shows the situation just after the definition of the local tmp object.
After executing swap (x, y), the value of x will be 4 while the value ofy will be 3,
i.e. the call to swap (x, y) will have swapped (hence the name) the values of x and
y.
1004 3 int x
1000 4 inty
int x(10);
int y(23);
int&
max(int& a,int& b) {
if (a>b)
return a;
else
return b;
}
max(x,y) = 25;
12 CHAPTER 1. BASIC CONCEPTS OF C++
Because the return type of the function is of a reference type, the function call will
result in an lvalue to which a value can be assigned (Section 1.2). Specifically, e.g.
the statement return a will execute int&: tmp (a) , which initializes a temporary
object of type int&: to contain a reference to (the object) a. Note that, in the example,
both a and b are reference parameters, thus ensuring that e.g. the object referred to by
a in return a does not live in the function call frame and, consequently, still exists
after the function call returns.
If the function max would take value parameters, the function would return a reference
to a parameter object (a copy of the original) which doesn't exist any more at the time
of the assignment max (x, y) = 25, a sure recipe for disaster.
I ReturnType FunctionName(ParameterDeclarationList);
Thus a function declaration is like a function definition where the actual body
has been replaced by a semicolon "; ".
The fragment below contains declarations for a double variable pi and a function
circle_area (definitions and declarations for types will be discussed in Chapters 4
and 6).
150ther widely used suffixes for C++ source file names are • cc and • cpp.
1.5. PROGRAM STRUCTURE 13
Upon reading a definition, the compiler will fully "implement" the concept, i.e. it will
• compute the detailed information, e.g. the size, of a defined type (note that,
contrary to the previous actions, processing a type definition does not have a
direct effect on the generated code).
In addition, the compiler will update its database so that when it next encounters the
name of the variable, function or type, it can react appropriately. On the other hand, a
declaration will only cause the compiler to enter the concept in its tables. The compiler
assumes that the concept will be defined elsewhere, e.g. in another translation unit, or
further on in the same translation unit.
00000000 <factorial(int»:
0: 55 pushl %ebp
1: 89 e5 moyl %esp,%ebp
3: 83 7d 08 01 cmpl $Ox1,Ox8(%ebp)
7: 7f 09 jg 12 <factorial(int)+Ox12>
9: b8 01 00 00 00 moyl $Ox1,%eax
e: eb 24 jmp 34 <factorial(int)+Ox34 >
10: eb 1e jmp 30 <factorial(int)+Ox30>
12: 8b 45 08 moyl Ox8(%ebp),%eax
15: 48 decl %eax
16: 50 pushl %eax
17: e8 e4 ff ff ff call o <factorial(int»
1c: 83 c4 04 addl $Ox4,%esp
1f: 89 cO moyl %eax,%eax
21: 89 c2 moyl %eax,%edx
14 CHAPTER 1. BASIC CONCEPTS OF C++
We notice that the code for the factorial function contains 53 (35 in hexadecimal
notation) bytes. At run-time, this code object will reside somewhere in memory and its
address is available to a C++ program via the name ofthe function (see Section 5.5).
The C++ compiler contains two modules that are organized in a "pipeline", as shown
in Figure 1.8.
C++ compiler
preprocessor compiler
The preprocessor module (usually also available as a separate program called cccp
or cpp) reads the source text file and processes any directives it encounters in the
source text. Such directives are not passed on to the compiler proper; they can be
distinguished from ordinary C++ source text by the occurrence of a # character at the
beginning of a line.
The most important directives, for our purposes, are
#include "filename" This directive causes the preprocessor to process the file
called filename before continuing processing the current source text. Note
that filename may itself contain preprocessor directives (including #in-
clude directives).
• The source file pi. C contains the definition of a double variable pi. The file
pi. h contains the corresponding declaration.
• The source file circle. C contains the definition of two functions, cir-
cle_area and circle_circumference. The corresponding declarations
can be found in the header file circle. h.
• The source file progl. C contains the definition of a single function main.
There is no corresponding header file.
16 As a matter of fact, the preprocessor is a full, but not very sophisticated, macro processor. However,
using this facility tends to make source text less understandable and is therefore discouraged.
16 CHAPTER 1. BASIC CONCEPTS OF C++
Note the line # inc 1 ude "pi. h": this will cause the compiler to include the text
of the header file pi. h in the source text at that point. If we made the mistake of
declaring pi as an integer variable in pi. h the compiler would complain with a
message explaining the inconsistency of the declaration with the definition
#ifndef PLH
#define PLH
extern double pi;
#endif
#ifndef PI...H
#def ine PI...H
#endif
are typical for the structure of a header file: the first line #ifndef PI...H will cause
the preprocessor to check whether the compile-time variable PI...H is defined. If so,
all following lines will be skipped until a matching #endi f directive is found. If,
however, PI...H is not defined, then the following lines are processed. In that case,
the next line #define PI...H defines the variable PI...H by setting its value to 1.
The overall effect is that, when compiling a translation unit, the declarations or type
definitions of the file pi . h will be processed at most once, even if the header file
pi.h is included many times (since #include directives may be nested, it may
be unavoidable that the same header file is included more than once, e.g. from other
different header files). Hence any type definitions in the header file are processed only
once by the compiler (defining the same type twice will cause the compiler to generate
an error, even if both definitions are identical).
The file circle. C contains the definitions of two functions, circle_area and
circle_circumference.
#include "pi.h"
#include "circle. h"
double
circle_circumference(double radius) {
return 2 * pi * radius;
}
1.5. PROGRAM STRUCTURE 17
double
circle_area(double radius) {
return pi * radius * radius;
}
#ifndef CIRCLE_H
#define CIRCLE_H
double circle_circumference(double radius);
double circle_area(double radius);
#endif
Finally, the file progl. C contains the definition of a single function called main.
#include "circle.h"
int
mainO {
double r(3.5);
circle_area(r);
return 0;
}
Every program must have exactly one such function in some translation unit: when
starting the program, the system will simply perform a function call to the function
main; as soon as this call is finished, the program will exit with a return code that
equals the value returned by the main function. The main function may return any
int value but, by convention, a value of 0 means that the program's execution was
successful, i.e. without errors, while any other return value indicates an error. Note
that this convention makes sense: there may be many reasons why the execution of
a program fails and the programmer can choose a particular return value to represent
each of them separately: e.g. 1 can be used to indicate that some input value was
illegal while 2 can be used to signal that the program ran out of memory, etc.
circle.o
! circle_circumference
! circle_area
? pi
pi.o prog
! pi
H linker r----- ! main
! circle circumference
! circle=:area
! pi
progl.o
! main
? circle_area
will also relocate the code in the object files such that the different (code or data)
objects do not overlap in the executable file.
As an example, the following listing shows a fragment of the progl . 0 object file.
00000000 <main>:
0: 55 pushl %ebp
08048710 <main>:
8048710: 55 pushl %ebp
08048768 <circle_area(double»:
8048768: 55 pushl %ebp
Note that the correct address of the circle_area code object has been filled in and
that the address of the main function has changed from 0 to 8048710 hex.
1.6. SYNTACTIC AND LEXICAL CONSIDERATIONS 19
• Types have a name that starts with a capital letter. If the name contains several
words, we capitalize the first letter of each word. E.g.
HttpRequest, Student
17It is not recommended, however, to start an identifier with an underscore since the compiler may gen-
erate extra symbols starting with one or several underscores; thus possibly causing a conflict.
20 CHAPTER 1. BASIC CONCEPTS OF C++
• Variables and functions have a name that starts with a lower case letter. If the
name contains several words, we use underscores to separate them. E.g.
• Constant (see Section 5.1) names are all upper case, with underscores separating
constituent words. E.g.
1.6.2 Comments
Even with well-chosen names, the purpose of a piece of source code may not be
obvious. That is why it is imperative to liberally sprinkle comments in the source
text. Comments are thus documentation text that is added to the source code.
Syntactically, the C++ compiler ignores
• any text that follows" / !" until the end of the line, and
Usually, only the first possibility is used; the second option is reserved for temporarily
"commenting out" a block of code, e.g. for debugging purposes.
As a minimum, each non-trivial definition should be preceded by a comment stating
the purpose of the various aspects of the definition. For a function, this can be fur-
ther enriched by specifying the pre- and postconditions associated with the function.
Moreover, each source text file should start with a comment detailing its author(s),
modification history and other administrative data 18 .
The sample below shows a fragment of a well-documented header file.
#define ERR_H
// $Id: err.h,v 1.5 2001/02/28 12:47:02 dvermeir Exp $
// Error message & error exit routines.
void err_msg(const char* fonnat, ... );
// Like fprintf(stderr, . .).
void err_exit(int status,const char *fonnat, ... );
// Like printf(. .), precedes printing by "Fatal error: "; follows printing by \n;
// also prints message associated with last system error (errno), which mayor may
// not be useful. Never returns (calls exit(status)).
void err_abort(const char *fonnat, ... );
// Use this if you want a core dump (abort()), in addition to the functionality of err_exit().
#endif
A common mistake is to insert comments that do not add anything to the understanding
of the code, as illustrated in the following fragment.
18 Such infonnation can be easily inserted and automatically maintained using a source code control
system such as cvs.
1.7. SCOPES AND NAMESPACES 21
A major problem with comments is that, as the code evolves, because of bug fixes or
changes to its functionality, the comments are not updated, e.g. because of laziness or
time pressure. This should be avoided at all cost: it is better not to have comments
than to have comments that are inconsistent with the code.
1.7.1 Scopes
In C++, the collection of all identifiers used in a program is not a flat set where every
name must uniquely identify one concept. This would be unacceptable since large
programs may contain tens of thousands of concepts and it would be a nightmare to
ensure that they all have different names.
Instead, names are organized in scopes where a scope can be thought of as a piece of
source text wherein names must be unique. The same identifier can be used to mean
different things in different scopes.
Scopes can be nested, so a fragment of source text can belong to many different scopes.
A particular occurrence of an identifier must then be interpreted using the meaning it
has in the most closely nested scope to which it belongs.
Most scopes are established as a side effect of a definition. E.g. a function definition
(see Section 3.3) defines a scope encompassing the whole definition, as shown in
Figure 1.10.
There are two definitions of the identifier x in this fragment; there is no conflict be-
cause the definitions are in different scopes: in the global (encompassing) scope x is a
double variable, while in the local scope, which corresponds to the definition of the
function f, x denotes an in t variable. The meaning of the other occurrences of x can
be easily determined using the "most closely nested scope" rule: the "a" occurrence
lies in the function scope and thus it refers to the int variable. The "b" occurrence
is in the outer scope and therefore refers to the double variable. On the other hand,
since the function definition does not redefine z, both uses of z refer to the double
variable in the global scope.
22 CHAPTER 1. BASIC CONCEPTS OF C++
global scope
x is double
z =f(3) + x;
b
1.7.2 Namespaces
Namespaces are explicitly defined scopes: a definition of the form
namespace OptionalNamespaceName {
SourceCode
}
will create a named scope containing all names declared in SourceCode l9 • Like
scopes, namespaces can be nested.
namespace A {
int x;
namespace C {
int x;
}
}
namespace B {
int x;
}
int
mainO {
int z(2);
z = x;
}
The above code defines three namespaces A and Band C: A contains two names: x
and C; Band C just contain x. With the nameless scope associated with the function
19The name is optional; if it is omitted, the system will generate a unique name for the namespace. This
makes such namespaces practically unaccessible from outside. However, as an exception, the names defined
in such an unnamed namespace are still accessible from the translation unit where they are defined.
1.7. SCOPES AND NAMESPACES 23
definition, this yields a scope structure as in Figure 1.11. The statement z = x will
global scope l
Ai ~
x ~
Cb
_ - scope of function definition
l z J
Figure 1.11: Namespaces.
cause the compiler to complain about x not being declared. Indeed, the function
definition scope where the statement appears does not contain a declaration of a name
x. On the other hand, the only encompassing scope, that is the global scope, does
not contain a declaration of x either. Consequently, no x is visible from within the
function definition scope.
To fix the problem we can use the scope resolution operator (": : "): if Scope refers to
a scope then
Scope: : name
refers to the name contained in Scope. Thus, we can make the statement z = x refer
to the x defined in C by writing
z = A::C::x;
instead of z = A::C::x.
It is also possible to import all the names of a namespace with a using directive:
namespace A {
namespace C {
extern int x; II only a declaration
}
}
namespace B {
int x;
}
int
mainO {
int z(2);
using namespace A::C;
z = x;
}
In the above code, the namespace A initially just contains a nested namespace C but is
later extended to also contain x. Also, A: : C: : x is only declared, not defined, within
the namespace A: : C. The subsequent definition
int A:: C:: x;
20 Some compilers, including the one used in this book, silently assume such a using directive.
Chapter 2
Built-in Types
int An object of this type represents an integer. An object of type int has a size
which is "convenient" for the underlying hardware (typically 32 bits). Integer
literals are written in the usual notation, e.g. 3241, 0, -123. Integer constants
can also be written in hexadecimal notation: simply prefix the hexadecimal
number with "Ox", as in Oxffff of Oxl00aSfff. Furthermore, any integer
literal that starts with "0" is considered to be in octal notation: 010 = S.
short An object of this type also represents an integer, but its size is typically smaller
than the size of into E.g. on 32-bit machines, a short may be 16 bits. Short
constants are written as normal integer constants.
long This is also an integer type but its size may exceed the size of an into Long
integer constants consist of an integer constant optionally followed by a suffix
"L". E.g. the constant 255L will be treated as a long integer by the compiler,
although a short object would suffice to hold it (if no suffix is used, the com-
piler will automatically determine a suitable type for an integer constant).
double A double object represents a double-precision floating point (i.e. real) num-
ber. Besides the usual notation, e.g. -1. 23,3.14, double literals can also
be written in scientific notation, e.g. 4. 23E12 for 4.23 x 10 12 or O. 67E-5
for 0.67 x 10- 5 . A double object usually takes 64 bits.
25
26 CHAPTER 2. BUILT-IN TYPES
float A float object represents a single-precision floating point number. Its size
does not exceed the size of a double. To write a float literal, simply use
a double literal immediately followed by the letter "F" (or "f"): 4. 23f,
o .13E-3F.
boot An object of this type represents a boolean value. There are two boolean literals
representing the classical truth values using the keywords true and false.
Internally, true and false are represent by the integer values 1 and 0, re-
spectively.
char A char object represents a letter in some standard encoding alphabet, usually
ASCII. The size of a char object is almost always 8 bits, i.e. a single byte.
Character constants are written between single quotes, e.g. ' a " , 0 ' , etc. In
addition, one can use the underlying integer to represent a character with that
code: simply write ' \x' where X is a number in octal notation, or ' \xY'
where Y is a number in hexadecimal notation. E.g. ' \12' and' \xa' both
represent the newline character (with decimal code 10). In addition, there are
some standard names to represent certain characters, as shown in Table 2.1.
wchar _t The wchar _t (wide character) type is used to represent chars from a larger
character set such as unicode. A wide character constant is of the form L' s '
where s is a sequence of characters. The size of s and its meaning are implemen-
tation dependent.
For each of the integer types (int, short, long), there is an unsigned variant which
interprets the same storage area as the original type as an unsigned number. These un-
signed variants are obtained by prefixing the original type name with the "unsigned"
keyword: unsigned short, unsigned intI and unsigned long. The ex-
tra bit, which is otherwise used for representing the sign, doubles the size of the
largest number that can be represented. E.g. if the size of a short integer is 16
1Actually, unsigned int may be abbreviated as unsigned.
2.2. CONVERSIONS FOR ARITHMETIC TYPES 27
bits; it can represent any integer in the [-32768 ... 32767] interval. The range of
unsigned short then becomes [0 ... 65535] (note that both ranges contain ex-
actly 216 = 65536 integer numbers). For 32-bit int values, the ranges become
[-2147483648 ... 2147483647] and [0 ... 4294967295].
The integer types, as well as the bool, char and wchar _t types, are called inte-
gral types because their underlying implementation is an integer number. All integral
types, as well as the floating point types support the usual arithmetic operations. Such
types are also called arithmetic types. The various categories of primitive types are
shown in Figure 2.1.
arithmetic types
integral types
integer types floating point types
int float
unsigned int double
short long double
unsigned short
long
unsigned long
char
unsigned char
signed char
bool
long I( , a ,); / / char fits into I. no problem; I will be 97, the ascii code for 'a'
int i(3.14); / / compiler will generate a warning; i will be 3
The first line defines a long object 1 which is initialized from a char value I a I •
Although the types of the value (a char) and the receiving object (a long) do not
match, the compiler will not complain because it is able to convert a char value to
a long value without loss of information. Indeed, since both char and long are
integral types, and the size of a char certainly does not exceed that of a long, such a
conversion can easily be performed and, consequently, the compiler will not complain
about it.
28 CHAPTER 2. BUILT-IN TYPES
The second line is a different matter: here we initialize an int object i with a dou-
ble value 3.14 and there is no way that we can accurately convert this value to an
into Hence the compiler \lIill give a warning
It will however not generate an error; instead it will simply do its best to approximate
(actually truncate) 3.14 by an int value. This will result in i being initialized to 3.
In general, for a definition or an assignment that attempts to store a value of an arith-
metic type tl into an object of a different arithmetic type t2, the compiler will do the
following:
Most conversions are as expected, e.g. converting a floating point type to an integral
type involves truncation. Converting a larger type to a smaller one (e.g. an unsigned
long to an int) may give strange results. Conversion to a bool will yield false
for a source value of 0 while any other value will yield true.
A different problem arises with expressions containing (references to) values of dif-
ferent arithmetic types, as in the example below.
double d(0.5);
float [(0.6);
int itO);
i = d + [; II i will become 1
Here the resulting value of i will be 1: the compiler will first convert, without loss of
information, the value of f to a double, then compute the expression, yielding 1.1,
and then convert the result to an into
In general, for an arithmetic operation involving values of different arithmetic types,
the compiler will figure out the most appropriate type t to perform the computation
without information loss. All operands will be promoted (converted) to t and the
operation is performed. The result may then be further converted, e.g. to fit it into a
receiving object.
operator can be thought of as a function. E.g. the "logical and" operation, denoted
"&:&:", can be considered a function
The corresponding C++ function declaration for such operator functions can be writ-
ten as follows:
bool operator&:&:(bool,bool);
As a matter of fact, C++ allows the programmer to define her own implementation
for many operators on user-defined types using a syntax like the one above, see Sec-
tion 4.2.12, page 63.
The following operations are defined for arithmetic types.
• The simple binary arithmetic operations: addition (+), subtraction (-), mul-
tiplication (*) and division (I). Note that, due to conversions (Section 2.2),
expressions may contain values of different types, e.g. 0 • 5 * true + ' a '
is legal and will result in a double value.
• The % operator computes the remainder of the integral division of the first
operand by the second: e.g. 7 % 2 returns 1. The % operator does not work on
floating point types.
a1 == a2 a1 is equal to a2
a1 != a2 a1 is not equal to a2
a1 < a2 a1 is strictly smaller than a2
a1 > a2 a1 is strictly greater than a2
a1 <= a2 a1 is not greater than a2
a1 >= a2 a1 is not smaller than a2
• Several operators manipulate the underlying bit pattern of integral type objects:
- The binary operator« shifts the bits in the first operand to the left by the
number of positions indicated by the second operand (the open positions
will be filled by 0). E.g. 1 « 10 will yield 1024, i.e. 210.
- The binary operator » shifts the bits in the first operand to the right by
the number of positions indicated by the second operand. E.g. 1025 »
1 0 will yield 1.
- The bitwise complement operator (-) will replace each 0 by a 1 and each
1 by a O. E.g. -0 will yield -1, assuming int objects are represented
using 2's complement notation.
- The &: operator can be used to perform a "bitwise and" operation on its
operands: x&:4 will be different from 0 iff x has its third bit set.
Similarly, I and ~ perform bitwise or and bitwise xor (exclusive or).
30 CHAPTER 2. BUILT-IN TYPES
• The« and» operators are overloaded (see Sections 3.2 and 4.2.12): besides
the bitshift operations (page 29), they also have a definition as input/output op-
erators: for an arithmetic value a,
out « a
will write a to the output stream ou t, while, for an lvalue la of some arithmetic
typeT
in » la
will attempt to read a value of type T into the object referred to by la. Note that
this interpretation of « and » is not part of the language proper. It is provided
by the standard iostream library (Chapter 10), e.g. by the definition of functions
like
ostream& operator«(ostream&,int);
istream& operator»(istream&,char&);
where istream is a (class) type, also defined in the iostream library, repre-
senting an input stream.
The iostream library provides some standard stream objects: cout is an 0-
stream that represents the UNIX standard output. Standard input is available
as an istream object cin while cerr is another ostream representing
standard error.
Note that the « and » 110 operations take a reference to a stream and return
a reference to a stream. The fact that the stream is passed by reference should
not be surprising since the alternative call-by-value (see Section 1.4.3) would
involve copying a stream. The return value is actually a reference to the same
stream as the parameter stream. Together with the associativity of the « and
» operators, this allows for expressions like
• The increment operator ++ comes in two flavours: the prefix version ++la adds
1 to its single lvalue operand la and then returns the new value of lao The post-
fix version la++ also increments its lvalue operand la, but returns the original
(before the increment) value of this operand. The decrement operator - - is sim-
ilar to ++, the difference being that in both the prefix and postfix versions 1 is
subtracted from its argument.
copies a to (the object referred to by) the lvalue la but also returns a reference
to lao Because of this, one can write e.g.
x = y = z = 0;
x = ( y = ( z = 0»;
i.e. z will be set to 0, then y will be set to (the value of) z, and, finally, x will
be set to (the value of) y. The net result is that x, yand z are all set to o.
where another binary operator, instead of +, could have been used. This can be
abbreviated by using a compound assignment operator which better expresses
the programmer's intention (increment the value of x by an amount a):
X += a
Compound assignment operators exist for several binary operators: *=, 1=, %=,
+ =, -=, < < =, > > =, & =, I =and =. The type of a compound assignment operation
A
for a type T is
x = y *= 2;
will store the new value of y in the object x.
• The sizeof operator is actually defined on values of any type. It returns the
size, in bytes, of its arguments. In addition, one can also write sizeof (T)
where T is the name of a (built-in or user-defined) type; in that case the size (in
bytes) of an object of that type is returned. E.g. sizeof (long double)
returns 12 on a typical (early 2000) Linux notebook system.
32 CHAPTER 2. BUILT-IN TYPES
• For any type T, the notation T (a) , where a represents some value, denotes the
construction of a T-value out of a. The operator T () is called a value construc-
tor. This is very useful for user-defined types, for which the programmer can
define arbitrary constructor/initialization functions, see Section 4.2.7.
For built-in types, the operator is less useful: the only reasonable way to initial-
ize e.g. an integer is by giving it the value of another integer, as in int (34) .
One would expect that the value constructor operator could also be used to ex-
plicitly request a conversion, as in int (100.23) and indeed, this works in
most cases. Unfortunately, the compiler may2, when interpreting such an ex-
pression T (a) where T is a built-in type and a does not have the same size as
T, rudely truncate a to the size of T. E.g.
cout « short(100000000.0f);
prints -7936 3 . Still, the operator is useful when the construction of the T-
value is well-defined, e.g. when converting from integers to enumeration types,
see Section 4.3.
The value constructor operator may also be used without arguments: T () re-
turns the default value of the type T, see Section 4.2.7.
The relative precedence of the above operators is shown, in decreasing order, in Ta-
ble 2.2 where operators with the same precedence appear in the same "box".
"hello world"
will cause the compiler to allocate a data object containing a consecutive sequence of
characters, i.e. an array of char objects as shown in Figure 2.2.
Note that the double quotes surrounding the text are not present. Also, there is one
extra char at the end which contains a zero character (denoted I \ 0 I according to the
rules on page 26). Such objects are often called C strings because they were inherited
from the C language4 •
2This is not a requirement; e.g. g++, the gnu C++ compiler, seems to do a decent job in trying to do
reasonable conversions in all cases we tested.
3This behaviour is reminiscent of the C-style cast:
cout« (short)(lOOOOOOOO.Of);
4Por most applications, the C++ class type string provides a safer and more powerful alternative to
C strings.
2.4. STRING LITERALS 33
const char*
It is possible to split a single literal over several strings written one after the other. E.g.
#include <iostream>
int
mainO {
cout « "hello world\n";
}
Note the newline ( , \n ,) character embedded in the string literal: it ensures that the
cursor will go to the (beginning of the) next line on the screen.
To spread the output over two lines, one could either replace the space character after
"hello" by another ' \n' or one could simply spread the string literal over several
lines, as in the code below.
2.4. STRING LITERALS 35
#include <iostream>
int
main() {
cout« "hello
world
}
Random documents with unrelated
content Scribd suggests to you:
The Project Gutenberg eBook of Teresa of
Watling Street: A Fantasia on Modern Themes
This ebook is for the use of anyone anywhere in the United States
and most other parts of the world at no cost and with almost no
restrictions whatsoever. You may copy it, give it away or re-use it
under the terms of the Project Gutenberg License included with this
ebook or online at www.gutenberg.org. If you are not located in the
United States, you will have to check the laws of the country where
you are located before using this eBook.
Language: English
1904
CONTENTS
TERESA OF WATLING STREET
CHAPTER I—THE BANK
CHAPTER II—THE CIRCUS
CHAPTER III—CHINK OF COINS
CHAPTER IV—MR. PUDDEPHATT
CHAPTER V—FIRE
CHAPTER VI—THE DESIRE FOR SILVER
CHAPTER VII—NOLAN
CHAPTER VIII—THE PEER’S ADVICE
CHAPTER IX—A VISIT
CHAPTER X—MONEY-MAKING
CHAPTER XI—END OF THE NIGHT
CHAPTER XII—THE NAPOLEON
CHAPTER XIII—THE VASE
CHAPTER XIV—FEATHERSTONE’S RECITAL
CHAPTER XV—ARRIVAL OF SIMON
CHAPTER XVI—THE INTERVIEW
CHAPTER XVII—THE CLOSE
TERESA OF WATLING STREET
CHAPTER I—THE BANK
S
ince money is the fount of all modern romantic adventure, the
City of London, which holds more money to the square yard
than any other place in the world, is the most romantic of
cities. This is a profound truth, but people will not recognise it.
There is no more prosaic person than your bank clerk, who ladles
out romance from nine to four with a copper trowel without knowing
it. There is no more prosaic building than your stone-faced banking
office, which hums with romance all day, and never guesses what a
palace of wonders it is. The truth, however, remains; and some time
in the future it will be universally admitted. And if the City, as a
whole, is romantic, its banks are doubly and trebly romantic. Nothing
is more marvellous than the rapid growth of our banking system,
which is twice as great now as it was twenty years ago—and it was
great enough then.
Such were the reflections of a young man who, on a June
morning, stood motionless on the busy pavement opposite the
headquarters of the British and Scottish Banking Company, Limited,
in King William Street, City. He was a man of medium size, fair, thick-
set, well-dressed, and wearing gold-rimmed spectacles. The casual
observer might have taken him for a superior sort of clerk, but the
perfect style of his boots, his gloves, and his hat precluded such a
possibility; it is in the second-rate finish of his extremities that the
superior clerk, often gorgeous in a new frock-coat, betrays himself.
This particular young man, the tenor of whose thoughts showed that
he possessed imagination—the rarest of all qualities except honesty
—had once been a clerk, but he was a clerk no longer.
He looked at his watch; it showed three minutes to twelve o’clock.
He waited another minute, and then crossed through the traffic and
entered the sober and forbidding portals of the bank. He had never
before been inside a City bank, and the animated scene, to which
many glass partitions gave an air of mystery, would have bewildered
him had he not long since formed the immutable habit of never
allowing himself to be bewildered. Ignoring all the bustle which
centred round the various cash desks lettered A to F, G to M, and so
on, he turned unhesitatingly to an official who stood behind a little
solitary counter.
‘Sir?’ said the official blandly; it was his sole duty to be bland (and
firm) to customers and possible customers of an inquiring turn of
mind.
‘I have an appointment with Mr. Simon Lock,’ said the young man.
The official intensified his blandness at the mention of the august
name of the chairman of the British and Scottish Banking Company,
Limited.
‘Mr. Lock is engaged with the Board,’ he said.
‘I have an appointment with the Board,’ said the young man. ‘My
card;’ and he produced the pasteboard of civilization.
The official read:
Mr. Richard Redgrave, M.A.,
Specialist.
‘In that case,’ said the official, now a miracle of blandness, ‘be
good enough to step this way.’ Mr. Richard Redgrave stepped that
way, and presently found himself in front of a mahogany door, on
which was painted the legend, ‘Directors’ Parlour’—not ‘Board Room,’
but ‘Directors’ Parlour.’ The British and Scottish was not an ancient
corporation with a century or two of traditions; it was merely a joint-
stock company some thirty years of age. But it had prospered
exceedingly, and the directors, especially Mr. Simon Lock, liked to
seem quaint and old-fashioned in trifles. Such harmless affectations
helped to impress customers and to increase business. The official
knocked, and entered the parlour with as much solemnity as though
he had been entering a mosque or the tomb of Napoleon. Fifty
millions of deposits were manoeuvred from day to day in that
parlour, and the careers of eight hundred clerks depended on words
spoken therein. Then Mr. Richard Redgrave was invited to enter. His
foot sank into the deep pile of a Persian carpet. The official closed
the door. The specialist was alone with three of the directors of the
British and Scottish Bank.
‘Please take a seat, Redgrave,’ said Lord Dolmer, the only one of
the trio with whom Richard was personally acquainted, and to whom
he owed this introduction. ‘We shall not keep you waiting more than
a minute or two.’
The other directors did not look up. All three were rapidly signing
papers.
Richard occupied a chair upholstered in red leather, next the door,
and surveyed the room. It was a large and lofty apartment, simply
but massively furnished in mahogany. A table of superb solidity and
vast acreage filled the middle space—such a table as only a bank
director could comfortably sit at. As Richard gazed at that article of
furniture and listened to the busy scratching of pens, he saw, with
the prophetic vision characteristic of all men who are born to
success, that a crisis in his life was at hand. He had steadily risen
throughout his brief life, but he had never before risen so high as a
bank parlour, and the parlour of such a bank! His history, though a
short one, was curious. He came to London from Westmoreland at
the age of nineteen as a clerk in the Customs. From the first he
regarded his clerkship merely as a means to an end; what end he
had yet to ascertain. He paid particular attention to his clothes,
joined a large political club, and kept his eyes open. His personal
stock-in-trade consisted of a rather distinguished appearance, a
quiet, deliberate, and confident voice and manner, an imperturbable
good temper which nothing could affect, and a firm belief that he
could do anything a little better than the average doer of that thing.
He desired a University degree, and by working at night for four
years obtained the M.A. of London. He practised a little journalism of
the sensational kind, and did fairly well at that, but abandoned it
because the profits were not large enough. One Sunday he was
cycling down the Portsmouth Road, and had reached an hotel
between twenty and thirty miles from London, when he met with his
first real chance. A motor-tricycle had unaccountably disappeared
from the hotel during luncheon. The landlord and the owner of the
tricycle were arguing as to the former’s liability. Redgrave listened
discreetly, and then went to examine the barnlike coach-house from
which the motor-tricycle had been spirited away. Soon the owner,
who had instructed the police and bullied the landlord, and was now
forced to kick his angry heels till the departure of the afternoon train
back to London, joined him in the coach-house. The two began to
talk.
‘You are Lord Dolmer,’ said Redgrave at length.
‘How do you know that?’ asked the other quickly.
He was a black-haired man of forty, simply dressed, and of quiet
demeanour, save of unusual excitement.
‘I have seen you at the Constitutional Club, of which I am a
member. Did you know that a motor-tricycle disappeared from this
same hotel a fortnight ago?’
Lord Dolmer was impressed by the youth’s manner.
‘No,’ he said; ‘is that really so?’
‘Yes,’ said Redgrave, ‘only a fortnight ago. Strange coincidence,
isn’t it?’
‘Who are you? You seem to know something,’ said Lord Dolmer.
Redgrave gave his name, and added:
‘I am an officer in the Customs.’
That sounded well.
‘I fancy I could trace your tricycle, if you gave me time,’ he said.
‘I will give you not only time, but money,’ the peer replied.
‘We will talk about that later,’ said Redgrave.
Until that hour Richard had no thought of assuming the rôle of
detective or private inquiry agent; but he saw no reason why he
should not assume such a rôle, and with success. He calmly
determined to trace the missing tricycle. By a stroke of what is called
luck, he found it before Lord Dolmer’s train left. Over half of the
coach-house was a loft in the roof. Richard chanced to see a set of
pulleys in the rafters. He climbed up; the motor-tricycle was
concealed in the loft. The landlord, confronted with it, said that of
course some mischievous loiterers must have hoisted it into the loft
as a practical joke. The explanation was an obvious one, and Lord
Dolmer was obliged to accept it. But both he and Redgrave had the
gravest suspicions of the landlord, and it may be mentioned here
that the latter is now in prison, though not for any sin connected
with Lord Dolmer’s tricycle.
‘What do I owe you? Name your own sum,’ said Lord Dolmer to
Redgrave.
‘Nothing at all,’ Redgrave answered.
He had come to a resolution on the instant.
‘Give me some introductions to your friends.
It is the ambition of my life to conduct important private inquiries,
and you must know plenty of people who stand in need of such a
man as I.’
Lord Dolmer was poor—for a lord—and eked out a bare
competence by being a guinea-pig in the City, a perfectly respectable
and industrious guinea-pig. He agreed to Redgrave’s suggestion,
asked him to dinner at his chambers in Half Moon Street, and
became, in fact, friendly with the imperturbable and resourceful
young man. Redgrave obtained several delicate commissions, and
the result was such that in six months he abandoned his post in the
Customs, and rented a small office in Adelphi Terrace. His
acquaintance with Lord Dolmer continued, and when Lord Dolmer,
after a lucky day on the Exchange, bought a 5-h.p. motor-car, these
two went about the country together. Redgrave was soon able to
manage a motor-car like an expert, and foreseeing that motor-cars
would certainly acquire a high importance in the world, he cultivated
relations with the firm of manufacturers from whom Lord Dolman
had purchased his car. Then came a spell of ill-luck. The demand for
a private inquiry agent of exceptional ability (a ‘specialist,’ as Richard
described himself) seemed to die out. Richard had nothing to do,
and was on the point of turning his wits in another direction, when
he received a note from Lord Dolmer to the effect that Mr. Simon
Lock and the directors of the British and Scottish had some business
for him if he cared to undertake it.
Hence his advent in King William Street.
‘Let me introduce you,’ said Lord Dolmer, beckoning Redgrave
from his chair near the door, ‘to our chairman, Mr. Simon Lock,
whose name is doubtless familiar to you, and to my co-director, Sir
Charles Custer.’
Redgrave bowed, and the two financiers nodded.
‘Take that chair, Mr. Redgrave,’ said Simon Lock, indicating a fourth
chair at the table.
Simon Lock, a middle-aged man with gray hair, glinting gray eyes,
a short moustache, and no beard, was one of the kings of finance.
He had the monarchical manner, modified by an occasional gruff
pleasantry. The British and Scottish was only one of various
undertakings in which he was interested; he was, for example, at
the head of a powerful group of Westralian mining companies, but
here, as in all the others, he was the undisputed master. When he
spoke Lord Dolmer and Sir Charles Custer held their tongues.
‘We have sent for you on Lord Dolmer’s recommendation—a very
hearty recommendation, I may say,’ Simon Lock began. ‘He tells us
that you have a particular partiality for motor-car cases’—Richard
returned Simon Lock’s faint smile—‘and so you ought to be specially
useful to us in our dilemma. I will explain the circumstance as simply
as possible. Will you make notes?’
‘I never write down these details,’ said Richard. ‘It is safer not to.
My memory is quite reliable.’
Simon Lock nodded twice quickly and resumed:
‘We have a branch at Kilburn, in the High Street, under the
managership of Mr. Raphael Craig. Mr. Craig has been in our service
for about twenty years. His age is fifty-five. He is a widower with
one daughter. He came to us from an Irish bank. Professionally, we
have no fault to find with him; but for many years past he has
chosen to live thirty-five miles from London, at a farmhouse between
the town of Dunstable and the village of Hockliffe, in Bedfordshire.
Dunstable, you may be aware, is on the old Roman road, Watling
Street, which runs to Chester. He used to go up to Bedfordshire only
at weekends, but of late years he has travelled between his country
home and London several times a week, often daily. He owns two or
three motor-cars, and has once been summoned and convicted for
furious driving. It is said that he can come to London by road from
Dunstable in sixty minutes. When he stays in London he sleeps over
the bank premises in the suite of rooms which we provide for him,
as for all our managers.’
‘You say you have no fault to find with Mr. Craig professionally,’
said Richard. ‘He does not, then, in any way neglect his duties?’
‘The reverse. He is an admirable servant, and our Kilburn branch is
one of the most lucrative of all our branches. Mr. Craig has built up a
wonderfully good business for us in that suburb. Let me continue.
Last year but one a relative of Mr. Craig’s, an uncle or something of
that sort, reputed to be crazy, died and left him a hundred thousand
pounds, chiefly, one heard, in new silver coins, which the old miser
had had a mania for collecting, and kept in his cellars like wine. The
strange thing is that Mr. Craig, thus made rich, did not resign his
position with us. Now, why should a man of large fortune trouble
himself with the cares of a comparatively unimportant bank
managership? That aspect of the case has struck us as somewhat
suspicious.’
‘Highly suspicious,’ murmured Sir Charles Custer, M.P., out of his
beard.
‘You naturally—shall I say?—resent eccentricity in any member of
your staff?’ said Richard sagaciously.
‘We do, Mr. Redgrave. In a bank, eccentricity is not wanted.
Further—another strange fact—a month ago the cashier of our
Kilburn branch, a mediocre but worthy servant named Featherstone,
a man of fifty, whose brains were insufficient to lift him beyond a
cashiership, and who, outside our bank, had no chance whatever of
getting a livelihood in this hard world, suddenly resigned. He would
give no reason for his resignation, nor could Mr. Craig give us any
reason for it. In the following week Featherstone committed suicide.
No doubt you saw the affair in the papers. The man’s books were
perfectly straight. He was a bachelor, and had no ties that the police
could discover. Such is the brief outline of the case. Have you any
questions to ask?’
Redgrave paused. When, from ignorance or any other cause, he
had nothing to say, he contrived to produce an excellent effect by
remaining silent and peering through his gold-rimmed spectacles.
‘Only one,’ he said. ‘What do you want to know?’
‘We don’t know what we want to know,’ said Simon Lock abruptly.
‘We want to know anything and everything. Our suspicions are too
vague to be formulated, but, as directors of a great financial
undertaking, we are bound to practise precautions. We do not desire
to dismiss Mr. Craig without a reason. Such a course would be unfair
—and unprofitable.’
‘May I define your position thus?’ said Redgrave. ‘You do not
precisely fear, but you perceive the possibility of, some scandal,
some revelations, which might harm the general reputation of the
bank. And therefore you wish to know, first, why Mr. Craig runs
about Watling Street so much on a motor-car; second, why, being
possessed of a hundred thousand pounds, he still cares to work for
you; and third, why this Featherstone killed himself.’
‘Just so,’ said Simon Lock, pleased.
‘Just so,’ echoed Sir Charles Custer.
Lord Dolmer gave his protégé a smile of satisfaction.
‘I will undertake to assuage your curiosity on these points,’
Redgrave said, with that air of serene confidence which came so
naturally to him.
‘And your fee?’ asked Simon Lock.
‘If I fail, nothing. If I succeed I shall present my bill in due course.’
‘When shall we hear from you?’
‘In not less than a month.’
That evening Richard strolled up the Edgware Road to Kilburn, and
looked at the exterior of the Kilburn branch of the British and
Scottish. It presented no feature in the least extraordinary. Richard
was less interested in the bank than in the road, the magnificent
artery which stretches, almost in a straight line, from the Marble
Arch to Chester. Truly the Roman builders of that road had a glorious
disregard of everything save direction. Up hill and down dale the
mighty Watling Street travels, but it never deviates. After sixty years
of disuse, it had resumed its old position as a great highway through
the magnificence of England. The cyclist and the motorist had
rediscovered it, rejuvenating its venerable inns, raising its venerable
dust, and generally giving new vitality to the leviathan after its long
sleep.
To Richard Redgrave it seemed the avenue of adventure and of
success. His imagination devoured the miles between Kilburn and
Dunstable, and he saw the solitary farmhouse of Raphael Craig,
bank manager, motorist, and inheritor of a hundred thousand
pounds in virgin silver coin.
CHAPTER II—THE CIRCUS
A
week later—and in the meantime he had been far from idle—
Richard Redgrave arrived in Dunstable. It was a warm,
sunshiny, sleepy day, such as suited that sleepy town, and
showed off its fine old church and fine old houses to perfection.
There is no theatre in Dunstable, no concert-hall, and nothing ever
excites this staid borough save a Parliamentary election or the
biennial visit of Bosco’s Circus.
On the morning of Richard’s arrival Dunstable was certainly
excited, and the occasion was Bosco, who, with his horses, camels,
elephants, lions, bears, acrobats, riders, trapezists, and pavilions,
had encamped in a large field to the south of the town. Along the
whole of its length Dunstable, which consists chiefly of houses built
on either side of Watling Street for a distance of about a mile and a
half, was happily perturbed by the appearance of Bosco’s gigantic,
unrivalled, and indescribable circus, which was announced to give
two performances, at two-thirty and at seven-thirty of the clock.
And, after all, a circus which travels with two hundred horses (chiefly
piebald and cream), and with a single tent capable of holding four
thousand people, is perhaps worthy to cause excitement.
Richard determined to patronize Mr. Bosco’s entertainment—he
thought he might pick up useful information in the crowd—and at
two-thirty he paid his shilling and passed up the gorgeous but
rickety steps into the pavilion.
A brass band was playing at its full power, but above the noise of
the trumpets could be heard the voice of the showman—not Bosco
himself, but an individual hired for his big voice—saying, ‘Step up,
ladies and gentlemen. Today happens to be the thirtieth anniversary
of our first visit to this town, and to celebrate the event we shall
present to you exactly the same performance as we had the honour
of presenting, by special command, to Her Majesty the Queen at
Windsor last year. Step up, step up, and see our great spectacle, the
Relief of Mafeking! See the talking horse! See Juana, the most
beautiful rider in the world! Step up!
Children half-price to morning performance only.’ The big voice
made precisely this speech every day of his life all over England.
The circus was well filled, and the audience enthusiastic. The
clowns had an enormous success. As for Richard, he was more
interested in Juana, the horsewoman. She was a tall and beautiful
girl, apparently of the Spanish type. She rode, in a strictly
conventional park riding costume, a superb strawberry-roan mare,
which at her command waltzed, circled, caracoled, and did
everything except stand on its head. Mare and rider were equally
graceful, equally calm and self-contained. It was a charming item in
the programme, but somewhat over the heads of the audience, save
a few who knew a born rider when they saw one. An elephant was
brought in, a young man in Indian costume being perched on its
neck. The mare and the elephant went through a number of
evolutions together. Finally the mare reared and lodged her forepaws
on the elephant’s tremendous flank, and so situated the strange pair
made an exit which roused the house from apathy to wild
enthusiasm. Juana was vociferously recalled. She re-entered on foot,
holding her habit up with one hand, a light whip in the other. Richard
could not help being struck by the rather cold, sad, disdainful beauty
of the girl’s face. It seemed wrong that the possessor of such a face
should have to go through a series of tricks twice daily for the
diversion of a rustic audience.
‘That wench is as like Craig’s girl as two peas.’ Richard turned
quickly at the remark, which was made by one of two women who
sat behind him industriously talking. The other agreed that there
was some likeness between ‘Craig’s girl’ and the lovely Juana, but
not a very remarkable one.
Richard left his seat, went out of the pavilion, and walked round
the outside of it towards the part where the performers entered the
ring. Attached to the pavilion by a covered way was a smaller tent,
which was evidently used as a sort of green-room by the performers.
Richard could see within, and it happened that he saw Juana
chatting with a girl who was very much like Juana, though rather
less stately. The young man in Indian costume, who had ridden the
elephant, was also of the group. Soon the young man went to
another corner of the tent, and the two girls began to talk more
rapidly and more earnestly. Lastly, they shook hands and kissed,
Juana burst into tears, and her companion ran out of the tent.
Richard followed her at a safe distance through the maze of minor
tents, vans, poles, and loose horses, to the main road. A small,
exquisitely-finished motor-car stood by the footpath; the girl jumped
on board, pulled a lever, and was off in a northerly direction through
Dunstable up Watling Street.
‘Is that the road to Hockliffe?’ he asked a policeman.
‘Yes, sir.’
‘It’s Raphael Craig’s daughter, I bet,’ he said to himself, and for
some reason or other smiled a satisfied smile. Then he added, half
aloud, ‘But who is Juana?’
He went back to see the rest of the performance, and he had
scarcely sat down before he had cause to wish that he had remained
outside. The famous strawberry-roan mare, formerly ridden by
Juana, was making a second appearance as the talking horse, in
charge of the young man who had shone before in Indian costume,
but who now wore the dress of a riding-master. An attendant was
walking along the front benches with a bundle of numbered cards.
He offered one to Richard, and Richard thoughtlessly accepted the
offer. From that moment the eyes of the entire assemblage were
upon him.
Welcome to our website – the perfect destination for book lovers and
knowledge seekers. We believe that every book holds a new world,
offering opportunities for learning, discovery, and personal growth.
That’s why we are dedicated to bringing you a diverse collection of
books, ranging from classic literature and specialized publications to
self-development guides and children's books.
ebookbell.com