久久久久久久av_日韩在线中文_看一级毛片视频_日本精品二区_成人深夜福利视频_武道仙尊动漫在线观看

繼承 std::istream 或等價(jià)物

Inheriting std::istream or equivalent(繼承 std::istream 或等價(jià)物)
本文介紹了繼承 std::istream 或等價(jià)物的處理方法,對(duì)大家解決問題具有一定的參考價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧!

問題描述

我需要通過一個(gè)流橋接兩個(gè)庫.

I need to bridge two libraries over a stream.

QDataStream which is a stream from Qt

和其他庫中的一些函數(shù),看起來像這樣

and some function from another libraries that looks like this

void read_something(istream& i);

我無法控制 QDataStream 的創(chuàng)建方式,也不允許更改 read_somthing 函數(shù)的接口.

I have no control over how the QDataStream is created and I'm not allowed to change the interface of read_somthing function.

我首先想到的就是寫一個(gè)繼承istream并包裝QDataStream的類.以前有人這樣做過嗎?

The first thing I can think of is write a class that inherits istream and wraps QDataStream. Have anybody done that before?

如果我認(rèn)為的方法不正確,我想知道實(shí)現(xiàn)這一目標(biāo)的最佳方法是什么.

If what I thought wasn't the proper way, I wonder what is the best way to achieve that.

推薦答案

你應(yīng)該寫一個(gè)流緩沖,它使用 QDataStream readBytes 和 writeBytes 來實(shí)現(xiàn)它的功能.然后使用 rdbuf 將 streambuf 注冊(cè)到 istream(您也可以編寫一個(gè) istream 后代,在初始化時(shí)執(zhí)行此操作).

What you should do is write a streambuf which uses the QDataStream readBytes and writeBytes to implement its functions. Then register the streambuf into a istream with rdbuf (you can also write an istream descendant which does this when initialized).

Boost 包含一個(gè)旨在促進(jìn) streambuf 寫入的庫.使用它可能比理解 streambuf 接口更簡單(我個(gè)人從未使用過它,但我已經(jīng)編寫了多個(gè) streambuf;我會(huì)看看我是否有可以發(fā)布的示例).

Boost contains a library aiming at facilitating the writing of streambuf. It could be simpler to use it than understanding the streambuf interface (personally I never have used it but I've written multiple streambuf; I'll see if I've a example that I can post).

這里有一些東西(用法語評(píng)論——它來自fr.comp.lang.c++的法語常見問題解答——,我沒有時(shí)間翻譯,認(rèn)為留下它們比刪除它們更好)它將 FILE* 調(diào)用包裝成一個(gè)流緩沖.這也是使用私有繼承的一個(gè)示例:確保在基類之前初始化可能是成員的內(nèi)容.在 IOStream 的情況下,基類也可以接收一個(gè) NULL 指針,然后成員 init() 用于設(shè)置流緩沖區(qū).

here is something (commented in French -- it comes from the french FAQ of fr.comp.lang.c++ --, I have no time for translation and think it is better to leave them than to remove them) which wraps FILE* call into a streambuf. This also is a show case of a use of private inheritance: ensuring that what could be a member is initialized before a base class. In the case of IOStream, the base class could as well receive a NULL pointer and then the member init() used to set the streambuf.

#include <stdio.h>
#include <assert.h>

#include <iostream>
#include <streambuf>

// streambuf minimal encapsulant un FILE*
//    - utilise les tampons de FILE donc n'a pas de tampon interne en
//      sortie et a un tampon interne de taille 1 en entree car l'interface
//      de streambuf ne permet pas de faire moins;
//    - ne permet pas la mise en place d'un tampon
//    - une version plus complete devrait permettre d'acceder aux
//      informations d'erreur plus precises de FILE* et interfacer aussi
//      les autres possibilites de FILE* (entre autres synchroniser les
//      sungetc/sputbackc avec la possibilite correspondante de FILE*)

class FILEbuf: public std::streambuf
{
public:

  explicit FILEbuf(FILE* cstream);
  // cstream doit etre non NULL.

protected:

  std::streambuf* setbuf(char_type* s, std::streamsize n);

  int_type overflow(int_type c);
  int      sync();

  int_type underflow();

private:

  FILE*    cstream_;
  char     inputBuffer_[1];
};

FILEbuf::FILEbuf(FILE* cstream)
  : cstream_(cstream)
{
  // le constructeur de streambuf equivaut a
  // setp(NULL, NULL);
  // setg(NULL, NULL, NULL);
  assert(cstream != NULL);
}

std::streambuf* FILEbuf::setbuf(char_type* s, std::streamsize n)
{
  // ne fait rien, ce qui est autorise.  Une version plus complete
  // devrait vraissemblablement utiliser setvbuf
  return NULL;
}

FILEbuf::int_type FILEbuf::overflow(int_type c)
{
  if (traits_type::eq_int_type(c, traits_type::eof())) {
    // la norme ne le demande pas exactement, mais si on nous passe eof
    // la coutume est de faire la meme chose que sync()
    return (sync() == 0
        ? traits_type::not_eof(c)
        : traits_type::eof());
  } else {
    return ((fputc(c, cstream_) != EOF)
        ? traits_type::not_eof(c)
        : traits_type::eof());
  }
}

int FILEbuf::sync()
{
  return (fflush(cstream_) == 0
      ? 0
      : -1);
}

FILEbuf::int_type FILEbuf::underflow()
{
  // Assurance contre des implementations pas strictement conformes a la
  // norme qui guaranti que le test est vrai.  Cette guarantie n'existait
  // pas dans les IOStream classiques.
  if (gptr() == NULL || gptr() >= egptr()) {
    int gotted = fgetc(cstream_);
    if (gotted == EOF) {
      return traits_type::eof();
    } else {
      *inputBuffer_ = gotted;
      setg(inputBuffer_, inputBuffer_, inputBuffer_+1);
      return traits_type::to_int_type(*inputBuffer_);
    }
  } else {
    return traits_type::to_int_type(*inputBuffer_);
  }
}

// ostream minimal facilitant l'utilisation d'un FILEbuf
// herite de maniere privee de FILEbuf, ce qui permet de s'assurer
// qu'il est bien initialise avant std::ostream

class oFILEstream: private FILEbuf, public std::ostream 
{
public:
  explicit oFILEstream(FILE* cstream);
};

oFILEstream::oFILEstream(FILE* cstream)
  : FILEbuf(cstream), std::ostream(this)
{
}

// istream minimal facilitant l'utilisation d'un FILEbuf
// herite de maniere privee de FILEbuf, ce qui permet de s'assurer
// qu'il est bien initialise avant std::istream

class iFILEstream: private FILEbuf, public std::istream
{
public:
  explicit iFILEstream(FILE* cstream);
};

iFILEstream::iFILEstream(FILE* cstream)
  : FILEbuf(cstream), std::istream(this)
{
}

// petit programme de test
#include <assert.h>
int main(int argc, char* argv[])
{
  FILE* ocstream = fopen("result", "w");
  assert (ocstream != NULL);
  oFILEstream ocppstream(ocstream);
  ocppstream << "Du texte";
  fprintf(ocstream, " melange");
  fclose(ocstream);
  FILE* icstream = fopen("result", "r");
  assert (icstream != NULL);
  iFILEstream icppstream(icstream);
  std::string word1;
  std::string word2;
  icppstream >> word1;
  icppstream >> word2;
  char buf[1024];
  fgets(buf, 1024, icstream);
  std::cout << "Got :" << word1 << ':' << word2 << ':' << buf << '
';
}

這篇關(guān)于繼承 std::istream 或等價(jià)物的文章就介紹到這了,希望我們推薦的答案對(duì)大家有所幫助,也希望大家多多支持html5模板網(wǎng)!

【網(wǎng)站聲明】本站部分內(nèi)容來源于互聯(lián)網(wǎng),旨在幫助大家更快的解決問題,如果有圖片或者內(nèi)容侵犯了您的權(quán)益,請(qǐng)聯(lián)系我們刪除處理,感謝您的支持!

相關(guān)文檔推薦

How can I read and manipulate CSV file data in C++?(如何在 C++ 中讀取和操作 CSV 文件數(shù)據(jù)?)
In C++ why can#39;t I write a for() loop like this: for( int i = 1, double i2 = 0; (在 C++ 中,為什么我不能像這樣編寫 for() 循環(huán): for( int i = 1, double i2 = 0;)
How does OpenMP handle nested loops?(OpenMP 如何處理嵌套循環(huán)?)
Reusing thread in loop c++(在循環(huán) C++ 中重用線程)
Precise thread sleep needed. Max 1ms error(需要精確的線程睡眠.最大 1ms 誤差)
Is there ever a need for a quot;do {...} while ( )quot; loop?(是否需要“do {...} while ()?環(huán)形?)
主站蜘蛛池模板: 国产女人与拘做受免费视频 | 天天看天天操 | 一区免费观看 | 蜜桃日韩| 国产1区2区3区 | 一区二区在线 | 免费激情 | 国产视频精品在线观看 | 91精品国产手机 | 最新超碰 | 蜜桃视频一区二区三区 | 婷婷久久久久 | 国产一区二区三区色淫影院 | 欧美成人h版在线观看 | 色视频免费| 91精品国产一二三 | 亚洲高清视频一区二区 | 91亚洲一区| 欧美成人a∨高清免费观看 欧美日韩中 | 日韩国产欧美一区 | 一区二区三区四区不卡视频 | 日韩免费| 91欧美精品成人综合在线观看 | 日韩美女在线看免费观看 | 精品久久国产老人久久综合 | 日韩精品网站 | 精品www| 91久久国产 | 亚洲国产成人精品女人久久久 | 欧美国产在线一区 | 日韩欧美一区二区三区四区 | 欧美日韩亚洲视频 | 三级在线免费观看 | 欧美日韩不卡合集视频 | 一级黄色av电影 | 国产三级日本三级 | 欧美专区日韩专区 | 91久久精品国产 | 欧美一区二区在线播放 | 日韩免费福利视频 | 欧美色性 |