2012-04-24 17 views
5

Piszę klasy, która ma różne komunikaty wyjściowe. Chcę uczynić tę klasę ogólną i niezależną od platformy, więc myślę o przeniesieniu do niej odniesienia basic_ostream i może ona zrzucić wszystkie wiadomości do strumienia. Robiąc to, jeśli klasa jest używana w programie konsolowym, mogę przekazać do niej std :: cout i wyświetlić w oknie konsoli.Jak wyprowadzić z C++ std :: basic_ostream i ustawić operator << w wirtualny?

Mogę też przekazać wyprowadzony ostream i przekierować komunikat do niektórych składników interfejsu użytkownika, np. Skrzynka na listy? Jedyny problem polega na tym, że wprowadzający dane operator << nie jest funkcją wirtualną. Jeśli przekazuję do niej odwołanie do klasy pochodnej, zostanie wywołany tylko operator < <.

Czy istnieje sposób obejścia tego problemu? własna odpowiedź

+3

Dlaczego nie używać ogólnego interfejsu 'std :: ostream' i zmieniać ukryte' stre ambuf' w oparciu o twój kontekst? Brak funkcji wirtualnych. – mavam

+3

Nie można uczynić funkcji nie należącej do elementu wirtualnego. 'operator <<' nie jest członkiem 'basic_ostream', ale jest funkcją bezpłatną. –

+0

@MatthiasVallentin: Ale muszę przekazać klasy podstawowej std :: ostream odniesienie do mojej klasy. W takim przypadku moja klasa pochodna z operatora << ostream nigdy nie zostanie wywołana. –

Odpowiedz

1

Nan Zhang, opublikowany pierwotnie jako część pytania:

Kontynuacja: OK, tutaj jest pochodną std :: streambuf które realizuje wymaganą funkcjonalność:

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_; 
}; 

Aby korzystać ta klasa wystarczy utworzyć std :: ostream i zainicjować przy użyciu tego bufora

std::ostream os(new listboxstreambuf(some_list_box_object)); 
Powiązane problemy