1

std :: ostreamから派生した(ロギング用の)クラスがあります。削除すると、次のようになります。

class bsgs : public std::ostream {
public:

  bsgs(const std::string& msg = "") {
    // some setup work
  }

  ~bsgs() {
    // some cleanup work
  }

  template<typename T>
  bsgs& operator<<(const T& rhs) {
    os << rhs;
    return *this;
  }

private:
  std::ostringstream os;
};

このクラスは、デルタ圧縮など、必要ないくつかの特定のことを行うために作成しました。残念ながら、それは機能しません。出力をstd::ostreamに送信するための「set_out」関数を提供するサードパーティライブラリ(ソースはありますが、かなり大きくて乱雑です)に渡す必要があります。set_out関数のプロトタイプはまさにこれです:

void set_out(std::ostream *out=0, int level=1);

そして私がそれを次のように呼ぶなら:

set_out(&std::cout, 3);

また

set_out(&std::cerr, 5);

期待どおりの動作が得られます。しかし、私が書く場合:

bsgs logger;
set_out(&logger, 3);

ロガーのコンストラクタとデストラクタは期待どおりに呼び出されますが、呼び出されることoperator<<はありません。理由はわかりませんが、これが簡単な質問であることを願っています。この問題を解決できれば、準備は完了です。

誰かが正確に何が起こっているのか知っていますか?bsgs問題は、ライブラリには、ポインタではなくaへのポインタを渡しているという手がかりがないことですが、500行以上のコードに触れる必要があるように見えるstd::ostreamよりも広い範囲のオブジェクトを受け入れるようにライブラリを修正することです。std::ostream *避けたいのですが。

~~~~~~~~~~~~~~

編集#1:それが重要かどうかはわかりませんが、ライブラリset_out() = 0;のクラス階層の最上位に仮想関数があり、これは(私が見る限り)さまざまなサブクラスに実装されています。ライブラリを作成している場合はset_out非仮想)テンプレート関数を作成し、std :: ostreamに特化したものを提供しますが、使用可能なを定義する限り、ユーザーは好きなものを提供できoperator<<ます。ライブラリにこの変更を加えると、半日の編集が確実に行われるように見えます。たぶんもっと簡単な方法がありますか?

4

2 に答える 2

1

ライブラリには、ポインタをaに渡しているという手がかりはありませんbsgs。仮想関数をオーバーライドしているわけではなく、ポリモーフィズムは関係していません。

streambufストリームに関連付けられたストリームバッファ( )を実装して置き換えることostream::rdbufが、より実行可能なソリューションであることがわかる場合があります。

于 2011-03-13T12:50:13.977 に答える
1

いつでも使えます

std::ostringstream os;
set_out(&os, 3);

ostreamから派生させたい場合は、仮想であるstreambufの独自の実装を作成し、次のようなストリームを作成します。

std::ostream stream(new myStreamBuf);
set_out(&stream, 3);
于 2011-03-13T12:55:40.563 に答える