c – 继承std :: istream或等价物

前端之家收集整理的这篇文章主要介绍了c – 继承std :: istream或等价物前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
我需要通过一个流来连接两个库.
  1. QDataStream which is a stream from Qt

和另一个类似这样的库的一些功能

  1. void read_something(istream& i);

我无法控制如何创建QDataStream,并且我不允许更改read_somthing函数的接口.

我可以想到的第一件事是写一个继承istream并包装QDataStream的类.有人做过吗?

如果我认为不是正确的方法,我想知道什么是最好的方式来实现.

解决方法

你应该做的是写一个streambuf,它使用QDataStream readBytes和writeBytes来实现它的功能.然后使用rdbuf将streambuf注册到一个istream中(您也可以在初始化时编写一个istream descendant).

Boost包含一个旨在促进streambuf写作的图书馆.使用它可能比理解streambuf界面更简单(个人我从来没有使用过,但我已经写了多个streambuf;我会看看我有一个例子,我可以发布).

编辑:这里是一些(用法评论 – 来自法国的fr.comp.lang.c的常见问题解答,我没有时间翻译,认为最好离开他们,而不是删除它们)包装文件*调用streambuf.这也是使用私有继承的示例:确保在基类之前初始化什么可以是成员.在IOStream的情况下,基类也可以接收一个NULL指针,然后使用成员init()来设置streambuf.

  1. #include <stdio.h>
  2. #include <assert.h>
  3.  
  4. #include <iostream>
  5. #include <streambuf>
  6.  
  7. // streambuf minimal encapsulant un FILE*
  8. // - utilise les tampons de FILE donc n'a pas de tampon interne en
  9. // sortie et a un tampon interne de taille 1 en entree car l'interface
  10. // de streambuf ne permet pas de faire moins;
  11. // - ne permet pas la mise en place d'un tampon
  12. // - une version plus complete devrait permettre d'acceder aux
  13. // informations d'erreur plus precises de FILE* et interfacer aussi
  14. // les autres possibilites de FILE* (entre autres synchroniser les
  15. // sungetc/sputbackc avec la possibilite correspondante de FILE*)
  16.  
  17. class FILEbuf: public std::streambuf
  18. {
  19. public:
  20.  
  21. explicit FILEbuf(FILE* cstream);
  22. // cstream doit etre non NULL.
  23.  
  24. protected:
  25.  
  26. std::streambuf* setbuf(char_type* s,std::streamsize n);
  27.  
  28. int_type overflow(int_type c);
  29. int sync();
  30.  
  31. int_type underflow();
  32.  
  33. private:
  34.  
  35. FILE* cstream_;
  36. char inputBuffer_[1];
  37. };
  38.  
  39. FILEbuf::FILEbuf(FILE* cstream)
  40. : cstream_(cstream)
  41. {
  42. // le constructeur de streambuf equivaut a
  43. // setp(NULL,NULL);
  44. // setg(NULL,NULL,NULL);
  45. assert(cstream != NULL);
  46. }
  47.  
  48. std::streambuf* FILEbuf::setbuf(char_type* s,std::streamsize n)
  49. {
  50. // ne fait rien,ce qui est autorise. Une version plus complete
  51. // devrait vraissemblablement utiliser setvbuf
  52. return NULL;
  53. }
  54.  
  55. FILEbuf::int_type FILEbuf::overflow(int_type c)
  56. {
  57. if (traits_type::eq_int_type(c,traits_type::eof())) {
  58. // la norme ne le demande pas exactement,mais si on nous passe eof
  59. // la coutume est de faire la meme chose que sync()
  60. return (sync() == 0
  61. ? traits_type::not_eof(c)
  62. : traits_type::eof());
  63. } else {
  64. return ((fputc(c,cstream_) != EOF)
  65. ? traits_type::not_eof(c)
  66. : traits_type::eof());
  67. }
  68. }
  69.  
  70. int FILEbuf::sync()
  71. {
  72. return (fflush(cstream_) == 0
  73. ? 0
  74. : -1);
  75. }
  76.  
  77. FILEbuf::int_type FILEbuf::underflow()
  78. {
  79. // Assurance contre des implementations pas strictement conformes a la
  80. // norme qui guaranti que le test est vrai. Cette guarantie n'existait
  81. // pas dans les IOStream classiques.
  82. if (gptr() == NULL || gptr() >= egptr()) {
  83. int gotted = fgetc(cstream_);
  84. if (gotted == EOF) {
  85. return traits_type::eof();
  86. } else {
  87. *inputBuffer_ = gotted;
  88. setg(inputBuffer_,inputBuffer_,inputBuffer_+1);
  89. return traits_type::to_int_type(*inputBuffer_);
  90. }
  91. } else {
  92. return traits_type::to_int_type(*inputBuffer_);
  93. }
  94. }
  95.  
  96. // ostream minimal facilitant l'utilisation d'un FILEbuf
  97. // herite de maniere privee de FILEbuf,ce qui permet de s'assurer
  98. // qu'il est bien initialise avant std::ostream
  99.  
  100. class oFILEstream: private FILEbuf,public std::ostream
  101. {
  102. public:
  103. explicit oFILEstream(FILE* cstream);
  104. };
  105.  
  106. oFILEstream::oFILEstream(FILE* cstream)
  107. : FILEbuf(cstream),std::ostream(this)
  108. {
  109. }
  110.  
  111. // istream minimal facilitant l'utilisation d'un FILEbuf
  112. // herite de maniere privee de FILEbuf,ce qui permet de s'assurer
  113. // qu'il est bien initialise avant std::istream
  114.  
  115. class iFILEstream: private FILEbuf,public std::istream
  116. {
  117. public:
  118. explicit iFILEstream(FILE* cstream);
  119. };
  120.  
  121. iFILEstream::iFILEstream(FILE* cstream)
  122. : FILEbuf(cstream),std::istream(this)
  123. {
  124. }
  125.  
  126. // petit programme de test
  127. #include <assert.h>
  128. int main(int argc,char* argv[])
  129. {
  130. FILE* ocstream = fopen("result","w");
  131. assert (ocstream != NULL);
  132. oFILEstream ocppstream(ocstream);
  133. ocppstream << "Du texte";
  134. fprintf(ocstream," melange");
  135. fclose(ocstream);
  136. FILE* icstream = fopen("result","r");
  137. assert (icstream != NULL);
  138. iFILEstream icppstream(icstream);
  139. std::string word1;
  140. std::string word2;
  141. icppstream >> word1;
  142. icppstream >> word2;
  143. char buf[1024];
  144. fgets(buf,1024,icstream);
  145. std::cout << "Got :" << word1 << ':' << word2 << ':' << buf << '\n';
  146. }

猜你在找的C&C++相关文章