ostream
のみを使用して最初からのようなクラスを実装する方法printf
は?
私にとって、問題はフォーマット文字列の選択にあるように見えますが、これは実際には入力の型を識別し、精度を扱うことに等しいです
3 に答える
「のようなクラス」operator<<
によってオーバーロードするものを意味していると思います。ostream
オーバーロードがあるだけで、関数の引数の型を簡単に識別できます。たとえば、次のような場合があります。
ostreamlike& ostreamlike::operator<<(int x)
{
printf("%d", x);
return *this;
}
ostreamlike& ostreamlike::operator<<(float x)
{
printf("%f", x);
return *this;
}
出力の形式は、どちらのオーバーロードが選択されたかによって決まります。
考えてみてください、それはそのようなものかもしれません
#include <stdio.h>
class ostreamlike {
public:
ostreamlike(FILE* f_): f(f_) {}
ostreamlike& write(int n) {
fprintf(f, "%d", n);
return *this;
}
ostreamlike& write(const char* n) {
fprintf(f, "%s", n);
return *this;
}
private:
FILE* f;
};
// operator for types that is supported ostreamlike internally
template <typename type>
ostreamlike& operator<<(ostreamlike& stream, const type& data) {
return stream.write(data);
}
// external implementations to write using ostreamlike
ostreamlike& operator<<(ostreamlike& stream, bool data) {
return stream.write(data ? "true" : "false");
}
int main() {
ostreamlike s(stdout);
s << "hello " << 1 << " : " << true << "\n";
return 0;
}
それは、どれだけ本物に近づきostream
たいかによって異なります。それを適切に行いたいと仮定すると、streambuf
派生クラスも必要になります。ostream
フォーマットのみを行い、実際の I/O は内部streambuf
派生クラスによって行われます。はフォーマットされていない I/O であるため、 notstreambuf
を使用する必要があります。fwrite
printf
あなたの目標が既存のFILE*
ポインターで I/O を実行することだけである場合は、これが最適です。sayから 1 つのクラスを派生させ、次にstreambuf
saystreambuf_with_FILE
から別のクラスを派生させostream
ますostream_with_FILE
。streambuf_with_FILE
適切なメソッドをオーバーライドして実際の I/O を実行しostream_with_FILE
、内部streambuf_with_FILE
オブジェクトを持ちます。実際に必要なコードはほとんどありません。