2012-04-24 13 views
5

Sto scrivendo una classe che ha vari messaggi in uscita. Voglio rendere questa classe generale e indipendente dalla piattaforma, quindi sto pensando di passare un riferimento basic_ostream e può scaricare tutti i messaggi nello stream. In questo modo, se la classe viene utilizzata in un programma di console, è possibile passare a std :: cout e visualizzarla nella finestra della console.Come derivare da C++ std :: basic_ostream e rendere l'operatore << virtuale?

Oppure potrei passare ad un ostream derivato e reindirizzare il messaggio ad alcuni componenti dell'interfaccia utente, ad es. ListBox? L'unico problema è che l'inseritore di dati operator << non è una funzione virtuale. Se passo il riferimento alla classe derivata, verrà chiamato solo l'operatore basic_ostream < <.

C'è qualche soluzione per questo? propria risposta

+3

Perché non utilizzare l'interfaccia generica 'std :: ostream' e modificare il' stre di base ambuf? basato sul tuo contesto? Non sono necessarie funzioni virtuali. – mavam

+3

Non è possibile rendere virtuale una funzione non membro. 'operator <<' non è un membro di 'basic_ostream', ma una funzione libera. –

+0

@MatthiasVallentin: Ma ho bisogno di passare il riferimento di classe base std :: ostream alla mia classe. In tal caso, la mia classe derivata dall'operatore << ostream non verrà mai chiamata. –

risposta

1

Nan Zhang, in origine pubblicato come parte della domanda:

Follow up: OK, ecco il derivato std :: streambuf che implementa richiesta la funzionalità:

class listboxstreambuf : public std::streambuf { 
public: 
    explicit listboxstreambuf(CHScrollListBox &box, std::size_t buff_sz = 256) : 
      Scrollbox_(box), buffer_(buff_sz+1) { 
     char *base = &buffer_.front(); 
     //set putbase pointer and endput pointer 
     setp(base, base + buff_sz); 
    } 

protected: 
    bool Output2ListBox() { 
     std::ptrdiff_t n = pptr() - pbase(); 
     std::string temp; 
     temp.assign(pbase(), n); 
     pbump(-n); 
     int i = Scrollbox_.AddString(temp.c_str()); 
     Scrollbox_.SetTopIndex(i); 
     return true; 
    } 

private: 
    int sync() { 
     return Output2ListBox()? 0:-1; 
    } 

    //copying not allowed. 
    listboxstreambuf(const listboxstreambuf &); 
    listboxstreambuf &operator=(const listboxstreambuf &); 

    CHScrollListBox &Scrollbox_; 
    std::vector<char> buffer_; 
}; 

Per utilizzare questa classe crea semplicemente uno std :: ostream e inizializza con questo buffer

std::ostream os(new listboxstreambuf(some_list_box_object)); 
Problemi correlati