函式需返回物件引用,但索引可能無效:
const Layer& Frame::GetLayer(uint32 layerIndex) const {
if (CheckLayerIndexValid(layerIndex))
return m_layers[layerIndex];
return ?; // 返回什麼?引用不能為 null
}
const Layer*,無效返回 nullptr。呼叫端需檢查。bool GetLayer(..., Layer& out)。語意清晰,但調用較繁瑣。嘗試保持引用返回,引入 Nullable<T> 基類,提供靜態空物件單例:
template<class T>
class Nullable {
protected: Nullable() {} virtual ~Nullable() {}
public:
static boost::shared_ptr<T>& NullPtr() { static boost::shared_ptr<T> p(Null()); return p; }
bool IsNull() { return this == ms_null; }
private:
static T* Null() { if (!ms_null) ms_null = new T; return ms_null; }
static T* ms_null;
static boost::shared_ptr<T> ms_nullPtr;
};
class Layer : public Nullable<Layer> { /* ... */ };
使用:return *Layer::NullPtr();,呼叫端需檢查 IsNull()。
std::optional<Layer> (C++17):明確表達「可能無值」,強制呼叫端處理,零開銷抽象。std::expected<T, E> (C++23):攜帶錯誤資訊。// Returns nullptr if not found)。空物件模式在特定領域(如 GUI 空控制項、策略模式預設策略)有價值,但不建議用於通用容器查找的引用返回。現代 C++ 提供 std::optional 等標準工具,能以類型系統保證安全,應優先採用。