2

それで、私はしばらく前から D に興味があり、少し前にいじりました。私はそれをもう一度見始めましたが、それが達成しようとしていることは本当に気に入っていますが、私のお気に入りの C++ 設計オプションの 1 つである非仮想インターフェイスについては懸念があります。

この設計で私が気に入っているのは、継承の階層の「最上位」で発生する前後の条件チェック、ロギング、およびリソース管理を可能にすることです。これにより、設計者は、関連するクラスのグループのすべての共通機能を指定し、クラスのカスタマイズ可能な部分を非常に小さな関数に分割できます。また、サブクラスに記述する必要がある機能の量も削減されます。さらに、仮想拡張ポイントはプライベートであるため、インターフェースを汚染したり、ユーザーが実装固有の関数を直接呼び出したりすることはありません (これが重要です)。

Dでこれを達成する方法はありますか?

C++ での例 (未テスト、未コンパイル...説明用)。

class Radio{
public:
  Radio( std::string id, Station defaultStation, RxChip chip)
    :defaultStation(defaultStation),
     id(id),
     chip(chip){
  }
  void turnOn() {
    log.trace("Radio turned on: id:[%s]", id.c_str());
    doEnableRx();
    doPostEnable();
    setToStation(defaultStation);
  }
  void turnOff(){
    log.trace("Radio turned off: id:[%s]", id.c_str());
    doDisableRx();
    doPowerOff();
  }
  void tune(){
    log.trace("Tuning");
    findAllStations();
  }
  void setToStation(Station target){
    logStationChange(target);
    doSetRxChipPassFilter(target);
  }
  void setChip(RxChip chip) {
    rxChip = chip;
  }
  RxChip getChip() {
    return rxChip;
  }
private:
  // doesn't start with "do" as this is considered a "normal" virtual function.
  virtual void findAllStations(){
    chip.setFrequency(chip.getLowFreq());
    setChipToNextTunedPoint();
    Station stat( chip.getFrequency(),  tunedStations.size() ); 
    tunedStations.push_back(stat);
  }
  virtual bool setChipToNextTunedPoint() {
    if(chip.isTuned()) {
      while( isTuned && chip.getFrequency() < chip.getHighFreq() )
        chip.incrementFreq();
    }
    while( !chip.isTuned() && chip.getFrequency() < chip.getHighFreq() ) 
      chip.incrementFreq();
    return chip.isTuned();
  }

  // "do" functions are considered mandatory extension points for sub-classes
  virtual void doEnableRx() = 0;
  virtual void doPostEnable() = 0;
  virtual void doDisableRx() = 0;
  virtual void doPowerOff() = 0;
  virtual void doSetRxChipPassFilter(Station target) = 0
  {
    //default implementation but it must be specified for use by sub-class.
    chip.setFrequency(target.getLowFreq());
    while( !chip.isTuned() && chip.getFrequency() < station.getHighFreq() ) {
      chip.incrementFreq();
    }
  }

  Station defaultStation;
  std::vector<Station> tunedStations;
  RxChip chip;

}
4

1 に答える 1