更多 C++ 慣用法/能力查詢
外觀
在執行時檢查物件是否支援某個介面。
將介面與實現分離是良好的面向物件軟體設計實踐。在 C++ 中,介面類 慣用法用於將介面與實現分離,並使用執行時多型性呼叫任何抽象的公共方法。擴充套件介面類慣用法中的示例,具體類可以實現多個介面,如下所示。
class Shape { // An interface class.
public:
virtual ~Shape();
virtual void draw() const = 0;
//...
};
class Rollable { // One more interface class.
public:
virtual ~Rollable();
virtual void roll() = 0;
};
class Circle : public Shape, public Rollable { // Circles roll - concrete class.
//...
void draw() const override;
void roll() override;
//...
};
class Square : public Shape { // Squares don't roll - concrete class.
//...
void draw() const override;
//...
};
現在,如果我們得到一個指向抽象類 Rollable 的指標的容器,我們可以簡單地對每個指標呼叫 roll 函式,如介面類慣用法中所述。
std::vector<Rollable *> rollables;
// Fill up rollables vector somehow.
for ( Rollable * rPtr : rollables )
rPtr->roll();
有時,我們無法提前知道物件是否實現了特定的介面。這種情況通常發生在物件從多個介面類繼承時。為了在執行時發現介面的存在與否,可以使用能力查詢。
在 C++ 中,能力查詢通常表示為在無關型別之間進行 dynamic_cast。
Shape *s = getSomeShape();
if (Rollable *roller = dynamic_cast<Rollable *>(s))
roller->roll();
這種 dynamic_cast 的用法通常稱為交叉轉換,因為它試圖跨越層次結構進行轉換,而不是向上或向下層次結構。在我們關於形狀和可滾動物件的示例層次結構中,dynamic_cast 到 Rollable 僅對 Circle 成功,而對 Square 則不成功,因為後者沒有從 Rollable 介面類繼承。
過度使用能力查詢通常表明面向物件設計存在缺陷。
- Dewhurst,Stephen C. "能力查詢"。C++ 常識。ISBN 0321321928.