Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the author emphasizes the fact that operator[] cannot return 0?

Tags:

c++

The code below was copied from Bruce Eckel's Thinking in C++ Volume 2 Chapter 16

//: C07:Wrapped.cpp
// From Thinking in C++, 2nd Edition
// Available at http://www.BruceEckel.com
// (c) Bruce Eckel 2000
// Copyright notice in Copyright.txt
// Safe, atomic pointers

#include <fstream>
#include <cstdlib>
using namespace std;
ofstream out("wrapped.out");

// Simplified. Yours may have other arguments.
template<class T, int sz = 1> class PWrap
{
    T* ptr;

    public:
    class RangeError {}; // Exception class
    PWrap() { ptr = new T[sz]; out << "PWrap constructor" << endl; }
    ~PWrap() { delete []ptr; out << "PWrap destructor" << endl; }
    T& operator[](int i) throw(RangeError)
    {
        if(i >= 0 && i < sz) return ptr[i];
        throw RangeError();
    }
};

class Cat
{
    public:
    Cat() { out << "Cat()" << endl; }
    ~Cat() { out << "~Cat()" << endl; }
    void g() {}
};

class Dog
{
    public:
    void* operator new[](size_t sz) { out << "allocating a Dog" << endl; throw int(47); }
    void operator delete[](void* p) { out << "deallocating a Dog" << endl; ::delete p; }
};

class UseResources
{
    PWrap<Cat, 3> Bonk;
    PWrap<Dog> Og;

    public:
    UseResources() : Bonk(), Og() { out << "UseResources()" << endl; }
    ~UseResources() { out << "~UseResources()" << endl; }
    void f() { Bonk[1].g(); }
};

int main()
{
    try
    {
        UseResources ur;
    }
    catch(int)
    {
        out << "inside handler" << endl;
    }
    catch(...)
    {
        out << "inside catch(...)" << endl;
    }
}

I have no problem with the code itself. But I'm having some trouble understanding the following comment about the class exception RangeError:

"The PWrap template shows a more typical use of exceptions than you’ve seen so far: A nested class called RangeError is created to use in operator[ ] if its argument is out of range. Because operator[ ] returns a reference it cannot return zero. (There are no null references.) This is a true exceptional condition – you don’t know what to do in the current context, and you can’t return an improbable value."

like image 287
Belloc Avatar asked Dec 22 '22 05:12

Belloc


1 Answers

If the function were to return a pointer rather than a reference, than it could signal failure (i.e. out-of-bounds index) by returning a NULL pointer. But you can't have NULL references, so the only option available is to throw an exception.*

As @Steve points out in comments below, you wouldn't want operator[] to return a pointer, because that would mean you'd need to write something like:

T x = *wrapper[5];


* An alternative would be to assert.
like image 135
Oliver Charlesworth Avatar answered Dec 24 '22 03:12

Oliver Charlesworth