2011-11-29 30 views
4

下面的代碼是從布魯斯Eckel的思考用C++複製第2卷第16章作者爲什麼強調operator []不能返回0的事實?

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

我有代碼本身沒有問題。但我有一些麻煩了解有關類異常RangeError以下注釋:

「的PWrap模板顯示一個比較典型的異常的使用比你迄今所看到:所謂RangeError一個 嵌套類創建如果參數超出範圍,則在operator[ ]中使用 因爲operator[ ]返回一個引用,所以它不能返回零(沒有空引用) 這是一個真正的例外條件 - 你不知道在當前上下文中做什麼,和 你不能返回一個不可能的值。「

回答

7

如果該函數返回一個指針而不是引用,則它可能會通過返回一個NULL指針來指示失敗(即超出邊界索引)。但是你不能有NULL引用,所以唯一可用的選擇是拋出一個異常。 *

由於@Steve在評論中指出的下方,你不會想operator[]返回一個指針,因爲這將意味着你需要寫類似:

T x = *wrapper[5]; 


*另一種方法是assert

+0

假設operator []返回一個指針,你將如何測試它的NULL值? – Belloc

+0

@ user1042389:您通常如何測試函數是否返回特定值?就像'T * ptr = something [i]; if(ptr == 0){/ * it null * /} else {/ *不是* /};'。但是,對於重載的'operator []'來說,返回一個指針並不是很有用,因爲它不會導致基於內置版本的操作符的語法。 –

+0

@SteveJessop謝謝史蒂夫。這回答了我的問題。 – Belloc

1

作者解釋得很好,也許零部分在消耗,他的意思是說他不能返回任何表示缺少價值的值(比如空指針),因此會引發適合。

0

作者說:「因爲operator []返回一個引用,所以它不能返回零。」因爲NULL引用是一件非常糟糕的事情。

3

他強調這一點,以解釋爲什麼在這種情況下拋出異常是唯一的選擇。

如果運算符返回一個指針,它可能會返回一個空指針,而不是在發生錯誤時拋出異常。但是因爲它返回一個引用,並且沒有空引用這樣的事情,所以處理錯誤的唯一方法是拋出一個異常。

+0

假設operator []返回一個指針,你將如何測試它的NULL值? – Belloc

+0

@ user1042389如果'operator []'返回了一個指針,那麼可以在對它進行解引用之前,通過使用'== NULL'來測試它是否爲null。 – sepp2k

相關問題