簡體   English   中英

C ++類設計:協方差

[英]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();
};    

實際上,它是工廠方法模式的應用程序,具有以下角色:

  • 相似度算法是工廠,
  • 具體算法是混凝土廠
  • ScoreCollection是產品
  • SymetricScoreCollection是具體產品

附加說明:

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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM