Thinking in C++ 2nd Edition

Author: Bruce Eckel
File Type: pdf
Size: 2,041 KB
Language: English
Pages: 593

Thinking in C++ 2nd Edition, Volume 2: Complete Guide to Standard Libraries & Advanced Topics

Introduction

Thinking in C++ Volume 2 (2nd Edition) by Bruce Eckel is more than just a sequel to Volume 1—it’s a substantial bridge from intermediate programming to advanced software craftsmanship. Released in the early 2000s and based on the ANSI/ISO C++ standard finalized in 1998, the book explores the Standard C++ Library in depth, while tackling sophisticated language features like templates, exception safety, multiple inheritance, and object-oriented design.

Though predating modern C++ revisions (C++11 and beyond), it remains a must-read for serious developers. It demonstrates how to write robust, reusable, and maintainable code by focusing on discipline, patterns, and clarity—skills that transcend language versions.


Background and Context

Bruce Eckel: The Author and His Influence

Bruce Eckel is a respected voice in the programming community, especially known for his ability to teach complex ideas with clarity. His “Thinking in…” series, which includes Thinking in Java and Thinking in C++, has helped thousands of developers worldwide move beyond syntax toward real understanding.

Volume 1 of Thinking in C++ introduces object-oriented C++ programming with an emphasis on clear examples. Volume 2, however, is where the depth kicks in. It’s aimed at those who already grasp the basics and want to build reliable systems.

The State of C++ When Volume 2 Was Written

Volume 2 was written during a transitional period for C++. The language had just been standardized, but major compiler support and best practices were still developing. The book focuses on features from the 1998–99 standard, before C++11 introduced modern concepts like move semantics, auto type deduction, and lambda functions.

However, this pre-C++11 foundation is still critical today, especially for understanding:

  • The mechanics behind STL (Standard Template Library)

  • Core design philosophies of C++

  • Manual memory management and RAII

  • Template metaprogramming origins

  • Exception handling and resource safety


What the Book Covers

Overview of Key Themes

The book breaks down into two major categories:

  • The Standard C++ Library: Strings, streams, STL algorithms and containers, and utilities

  • Advanced Language Topics: Templates, multiple inheritance, RTTI, exception safety, design patterns, testing, and multithreading foundations

Each topic is tackled through concise explanations, practical examples, and thoughtful exercises that reinforce key principles.


Part 1: The Standard C++ Library

1.1 Strings: Going Beyond char*

The book begins by transitioning readers from C-style strings (char*) to C++’s std::string and std::wstring. Eckel emphasizes the advantages:

  • Built-in memory management

  • Safe copying and comparison

  • Rich manipulation functions

He explores:

  • Construction and assignment

  • Append, insert, replace

  • Substring searches (find, rfind)

  • Iterators and string traits

  • Unicode considerations with std::wstring

Code Example:

std::string input = "Error: Disk Full";
if (input.find("Error") != std::string::npos) {
std::cout << "Found an error message.\n";
}

This section also compares performance and memory pitfalls between C-style and STL strings.


1.2 Iostreams and File Handling

Eckel provides an in-depth exploration of iostream, ifstream, ofstream, and stream manipulators:

  • Stream-based formatting: setw, setprecision, hex, fixed

  • Buffering control: flush, endl, sync_with_stdio

  • File stream usage and RAII-based safety

  • Binary vs text file operations

The beauty of C++ I/O lies in its extensibility. Eckel covers overloading operator<< and operator>> for custom types.

Use Case:
Reading a CSV file and parsing rows using getline() and std::stringstream.


1.3 STL Algorithms & Containers

Arguably one of the most important sections, Eckel introduces:

  • Containers: vector, list, deque, set, map

  • Iterators: input, output, forward, bidirectional, random-access

  • Algorithms: sort, find, transform, for_each, accumulate

  • Function objects and lambdas (pre-lambda via functors)

Code Snippet:

std::vector<int> data = {1, 2, 3, 4, 5};
std::transform(data.begin(), data.end(), data.begin(),
[](int x) { return x * x; });

Even though the lambda syntax wasn’t yet available, Eckel emulates it using structs with operator().


1.4 Utility Headers and Diagnostics

Eckel covers helpful but often underused headers:

  • <cassert> for assert()

  • <exception> and custom exception classes

  • <memory> for smart pointers (limited in pre-C++11)

  • <stdexcept> for specific error types like logic_error, bad_alloc

These form the foundation for safer, more expressive C++ code. Exception diagnostics, stack unwinding, and type safety are critical for writing large systems.


Part 2: Advanced Language Topics

2.1 Templates and Compile-Time Logic

This chapter explores the power and complexity of templates:

  • Function and class templates

  • Template specialization and partial specialization

  • Template instantiation and compiler behavior

  • Simple metaprogramming tricks

Example:

template<typename T>
T square(T value) {
return value * value;
}

It even includes how to simulate polymorphism with template-based strategies, sidestepping the cost of virtual tables.


2.2 Multiple Inheritance and RTTI

C++ allows multiple inheritance—a powerful but dangerous feature. Eckel discusses:

  • The “diamond problem”

  • Virtual inheritance

  • Alternatives using interfaces and composition

  • Runtime type identification (RTTI) using typeid and dynamic_cast

Design Tip: Favor interfaces and behavior delegation over deep inheritance trees.


2.3 Exceptions and RAII

Exception safety is crucial for maintainable C++. Eckel teaches:

  • Exception handling syntax

  • Types of safety guarantees:

    • Basic: No resource leaks

    • Strong: No side effects on failure

    • No-throw: Guaranteed not to throw

  • RAII (Resource Acquisition Is Initialization)

  • Cleanup strategies using destructors

RAII Pattern Example:

class FileWrapper {
std::ifstream file;
public:
FileWrapper(const std::string& path) : file(path) {}
~FileWrapper() { /* file closes automatically */ }
};

2.4 Design Patterns and System Architecture

A major strength of this book is how it introduces classic design patterns in real C++:

  • Factory Method

  • Observer

  • Singleton

  • Prototype

  • Visitor

These are implemented in idiomatic C++—demonstrating how templates and polymorphism play into larger software architectures.

Code Excerpt:
Implementing a basic Observer pattern using function pointers or functors for callback registration.


2.5 Defensive Programming and Unit Testing

Volume 2 advocates building systems that fail safely. Topics include:

  • Assertions and assumptions

  • Pre- and post-condition checking

  • Defensive copying

  • Minimal unit testing framework

  • Test harness creation and usage

Example:
A lightweight test macro system that registers test cases and runs them with output summaries.


2.6 Multithreading Foundations

Although C++ did not support multithreading natively at the time, this section introduces:

  • Concepts of concurrency

  • Thread safety and synchronization

  • Race conditions

  • Thread design patterns (Producer-Consumer, Mutexes)

This sets the stage for understanding C++11’s <thread> library later on.


Case Study: A File Log Analyzer

Problem

Build a batch tool that processes log files to filter and summarize error messages.

Solution Architecture

Input Stage

  • Uses std::ifstream to read files line-by-line

  • Employs stream manipulators for parsing

Parsing Stage

  • Applies std::string::find, substr to extract fields

  • Filters based on severity levels

Data Storage

  • Stores records in std::vector<LogRecord>

  • Defines LogRecord struct with timestamp, severity, message

Processing

  • Uses std::sort to order by time

  • Applies std::find_if with custom functors or lambdas

Output Stage

  • Writes formatted report via std::ofstream

  • Uses formatting functions like setw, left, right

Error Handling

  • Catches I/O errors via exceptions

  • Wraps files in RAII classes

Testing

  • Validates record parsing and summary counts

  • Uses assertions and test macros from the book’s framework


Challenges the Book Helps You Overcome

Challenge Eckel’s Approach
Deep Library Complexity Simplified examples, clear idioms
Multiple Inheritance Pitfalls Advocates safer alternatives
Template Code Bloat Selective usage with real tradeoffs
Exception Safety Strong RAII emphasis, cleanup guarantees
System Maintainability Modular design, patterns, consistent style

Getting the Most Out of the Book

Practice With the Code

Eckel provides all examples as compilable code. Copying and modifying them is the best way to internalize concepts.

Work Through the Exercises

Each chapter ends with hands-on challenges. Solutions are in the downloadable materials.

Translate to Modern C++

Try converting examples to C++11/14/17. Rewrite templates with auto, replace functors with lambdas, and use smart pointers where applicable.

Explore Design Patterns

Take a pattern like Observer and implement it in your own side project. This builds deep intuition.


FAQs On Thinking in C++ 2nd Edition

Is Volume 2 still relevant today?

Yes. While C++ has evolved significantly, the principles taught here are timeless. Modern C++ builds on these foundations.

Does it cover C++11 or newer?

No. But by mastering the pre-11 material, you gain insight into why later features matter.

Where can I download the book?

It’s freely available on Bruce Eckel’s site, micc.unifi.it, or the Internet Archive.

Do I need to read Volume 1 first?

Ideally, yes—Volume 1 builds the groundwork. Volume 2 assumes comfort with basic syntax and object-oriented programming.

How does it compare to other C++ books?

It complements texts like Stroustrup’s The C++ Programming Language and Meyers’ Effective C++, focusing more on learning through implementation than reference material.


Conclusion

Thinking in C++ Volume 2 is a masterclass in practical C++ development. It takes you from competent coder to serious developer—capable of building maintainable, scalable systems with confidence. From the intricacies of the STL to the challenges of exception-safe design and the elegance of design patterns, Bruce Eckel’s guidance remains insightful and effective.

Despite being written in a pre-C++11 world, its lessons endure. If you aim to build a rock-solid foundation in C++, this book—and the commitment it demands—is well worth your time.

Download
Scroll to Top