我有一個名為BaseStrategy. 它包含一個純虛函式calculateEfficiency()。有兩個類ConvolutionStrategy,MaxPoolStrategy它們派生自這個基類并實作自己特定版本的calculateEfficiency().
這是一些代碼:
class BaseStrategy {
public:
explicit BaseStrategy();
virtual ~BaseStrategy() = default;
private:
virtual double calculateEfficiency(mlir::Operation* op) = 0;
};
class ConvolutionStrategy : public BaseStrategy {
private:
double calculateEfficiency(mlir::Operation* op)
{
//some formula for convolution
return 1;
}
};
class MaxPoolStrategy : public BaseStrategy {
private:
double calculateEfficiency(mlir::Operation* op)
{
//some formula for MaxPool
return 1;
}
};
現在我有另一個類叫做StrategyAssigner. 它有一種方法calculateAllLayerEfficiencies(),其目的是遍歷網路中的所有層。根據層的型別,有一個 switch 陳述句,應該calculateEfficiency()根據層型別呼叫正確的。
class StrategyAssigner final {
public:
explicit StrategyAssigner(){};
public:
void calculateAllLayerEfficiencies() {
// Logic to iterate over all layers in
// a network
switch (layerType) {
case Convolution:
// Call calculateEfficiency() for Convolution
break;
case MaxPool:
// Call calculateEfficiency() for MaxPool
break;
}
};
}
int main ()
{
StrategyAssigner assigner;
assigner.calculateAllLayerEfficiencies();
}
我的問題是,我是否應該在類中存盤物件 Convolution 和 MaxPool 的參考,StrategyAssigner以便我可以呼叫各自的calculateEfficiency().
或者你能建議一個更好的打電話方式calculateEfficiency()。我真的不知道如何創建物件(聽起來很愚蠢)。
我不能將calculateEfficiency()它們設為靜態,因為我需要它們是虛擬的,以便每個派生類都可以實作自己的公式。
uj5u.com熱心網友回復:
如果您包含完整的代碼,我可以給出更詳細的答案,但您需要存盤使用派生類實體初始化的 BaseStrategy 指標。這是由您的一些代碼制成的示例:
std::vector<std::unique_ptr<BaseStrategy>> strategies;
strategies.emplace_back(new ConvolutionStrategy);
strategies.emplace_back(new MaxPoolStrategy);
for (int i = 0; i < strategies.size(); i) {
std::unique_ptr<BaseStrategy>& pStrat = strategies[i];
pStrat->calculateEfficiency(...);
}
請注意,這不會編譯,因為我沒有從您發布的代碼中獲得足夠的詳細資訊來實作它,但這顯示了如何以您需要的方式利用多型性。
此外,我使用智能指標進行記憶體管理;自行決定使用這些。
uj5u.com熱心網友回復:
您確實可以在這里使用運行時多型性:
- 宣告
~BaseStrategy虛擬(你已經在這樣做了 ;-) - 如果您永遠不會實體化 a
BaseStrategy,請將其方法之一宣告為虛擬純,例如calculateEfficiency(您也已經在這樣做了!)。我會做那個方法const,因為它看起來不會修改實體。而且它需要是公開的,因為它需要從StrategyAnalyser. - 宣告
calculateEfficiency為virtual和override在每個子類中。final如果您不希望子類覆寫它,也可能是這樣。 - 我會保留一個指向at
std::vector的智能指標。如果你認為這個類不會共享這些指標,你可以使用s。BaseStrategyStrategyAssignerunique_ptr - 現在的關鍵是您創建子類的堆實體并將它們分配給基類的指標。
class StrategyAssigner final {
public:
void addStrategy(std::unique_ptr<BaseStrategy> s) {
strategies_.push_back(std::move(s));
}
private:
std::vector<std::unique_ptr<BaseStrategy>> strategies_{};
};
int main()
{
StrategyAssigner assigner;
assigner.addStrategy(std::make_unique<ConvolutionStrategy>());
}
- 然后,當您
calculateEfficiency使用這些指標中BaseStrategy的任何一個呼叫時,運行時多型性將啟動,它將是子類的方法,即實際呼叫的方法。
class ConvolutionStrategy : public BaseStrategy {
private:
virtual double calculateEfficiency() const override {
std::cout << "ConvolutionStrategy::calculateEfficiency()\n";
return 10;
}
};
class MaxPoolStrategy : public BaseStrategy {
private:
virtual double calculateEfficiency() const override {
std::cout << "MaxPoolStrategy::calculateEfficiency()\n";
return 20;
}
};
class StrategyAssigner final {
public:
void calculateAllLayerEfficiencies() {
auto sum = std::accumulate(std::cbegin(strategies_), std::cend(strategies_), 0,
[](auto total, const auto& strategy_up) {
return total strategy_up->calculateEfficiency(); });
std::cout << "Sum of all efficiencies: " << sum << "\n";
};
};
int main()
{
StrategyAssigner assigner;
assigner.addStrategy(std::make_unique<ConvolutionStrategy>());
assigner.addStrategy(std::make_unique<MaxPoolStrategy>());
assigner.calculateAllLayerEfficiencies();
}
// Outputs:
//
// ConvolutionStrategy::calculateEfficiency()
// MaxPoolStrategy::calculateEfficiency()
// Sum of all efficiencies: 30
[演示]
轉載請註明出處,本文鏈接:https://www.uj5u.com/ruanti/430914.html
