[英]C++ class design: Covariance
我想實現許多在圖形上工作的算法,並返回節點對的分數,以指示這些節點是否相似。 該算法應在單個節點對和所有可能的節點對上工作。 在后一種情況下,應返回一個集合/矩陣。
該算法源自
class SimilarityAlgorithm {
public:
Base(const Graph& G);
virtual double run(node u, node v) = 0; // indices for nodes in the graph
virtual ScoreCollection& runAll() = 0;
}
現在,算法在內存使用方面有所不同。 一些算法可能是對稱的,並且(u,v)和(v,u)的分數相同。 這要求應返回不同的ScoreCollection類型。 一個示例是稀疏矩陣和三角矩陣,它們都從ScoreCollection
派生。
這將歸結為協變返回類型:
class SpecificAlgorithm : SimilarityAlgorithm {
public:
double run(node u, node v);
// The specific algorithm is symmetric and thus uses a symmetric matrix to save memory
SymmetricScoreCollection& runAll();
}
您的設計似乎適合於您描述的問題。
問題:
但是, SpecificAlgorithm
存在問題: runAll()
返回的類型與基類的虛函數不同。 因此它不會被調用(或者更可能是由於缺少虛函數而無法編譯您的代碼)。
解:
通過使SymmetricScoreCollection
成為ScoreCollection
的派生類,還可以對ScoreCollection
使用多態方法:
class SymetricScoreCollection: public ScoreCollection {
//define the member functions to access the values virtual
...
};
class SpecificAlgorithm : public SimilarityAlgorithm {
public:
double run(node u, node v);
// The specific algorithm is symmetric and thus uses a symmetric matrix to save memory
ScoreCollection& runAll();
};
實際上,它是工廠方法模式的應用程序,具有以下角色:
附加說明:
從runAll()
返回對ScoreCollection
的引用會帶來一些風險。 假設sa
是一個特定的算法。
在以下語句中:
ScoreCollection sc = sa.runAll();
sa.runAll()
返回對SymetricScoreCollection
的引用,但它將引用的對象復制到sc,從而使其成為ScoreCollection。 發生切片 ,多態將無法正常工作。
但是,以下語句將成功:
ScoreCollection& rsc = sa.runAll();
因為rsc是一個引用,它仍將引用由sa.runAll()
返回的原始SymetricScoreCollection
對象,並且一切都會按設計進行。
您會看到,返回引用時很容易出現未被注意的錯誤。 我建議返回一個指針而不是引用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.