2017-08-04 231 views
0

我對理解什麼是ostream是一個基本問題。我知道它是輸出流的基類,但是我不能很好地使用它,以及爲什麼要使用它而不是僅僅說std :: cout。 所以在這裏我有這個例子,我必須創建一個新的類名爲堆棧與pop()函數(就像在C++已經提供的類)。使用ostream作爲函數參數

這裏list_node是一個由兩個元素組成的結構體:鍵(它是一個整數)和一個指向下一個整數的interator。 list_node(已給)的

定義:

struct list_node { 
int key; 
list_node∗ next; 
// constructor 
list_node (int k, list_node∗ n) 
: key (k), next (n) {} 
}; 

這裏是類(已給出以及)的定義:

class stack { 
public: 
void push (int value) {...} 
... 
private: 
list_node∗ top_node; 
}; 

,這裏是與我的一部分遇到問題:

​​

我不明白他們爲什麼使用ostream &作爲函數參數。難道他們不僅僅把top_node作爲參數,而且還使用了.next函數(.next讀取下一個list_node),然後他們可以用std :: cout函數打印它。爲什麼這樣做會更好?

+3

首先,'std :: ostream'肯定是**不是**'std :: cout'的另一個名字。前者是基類,其次是未指定類型的對象。其次,目前還不清楚你在問什麼。 – SergeyA

+0

該方法是在堆棧內定義的嗎? 'top_node'是堆棧類的成員嗎?真的不清楚你在問什麼;它看起來像有很多遺漏的上下文。 –

+0

你應該提供[mcve] –

回答

0

爲什麼這樣做會更好?

我不確定你的問題,並不確定它是一種更好的方法。

也許是爲了靈活性。下面是從我的應用程序庫的例子:


當我宣佈一個數據屬性,作爲一個ostream

class T431_t 
{ 
    // ... 
    std::ostream*  m_so; 
    // ... 

我可以平凡使用屬性提供的報告「其中,m_so點」 。在這個應用程序中,有幾個例子* mso < < ...正在使用。這是主要的例子。

inline void reportProgress() 
{ 
    // ... 
    *m_so << " m_blk = " << m_blk 
     << " m_N = 0x" << std::setfill('0') << std::hex << std::setw(16) << m_N 
     << " " << std::dec << std::setfill(' ') << std::setw(3) << durationSec 
     << "." << std::dec << std::setfill('0') << std::setw(3) << durationMSec 
     << " sec (" << std::dec << std::setfill(' ') << std::setw(14) 
     << digiComma(m_N) << ")" << std::endl; 
    // ... 
} 

注意,在類的構造函數(構造函數),對於m_so到std ::法院缺省分配。

T431_t(uint64_t maxDuration = MaxSingleCoreMS) : 
     // .. 
     m_so (&std::cout), // ctor init - default 
     // .. 
{ 
    // ... 

當用戶選擇的雙線程處理選項,這是一個命令行選項在約1/2的時間通過使用我的桌面的兩個處理器來執行應用程序,該報告可以成爲如果我允許兩個獨立的輸出流交織(在用戶屏幕上),很難閱讀。因此,在由線程2運行的對象實例中,m_so的設置有些不同。

以下數據屬性捕獲並保留線程2輸出,以便稍後流式傳輸到std :: cout。

std::stringstream m_ssMagic; // dual threads use separate out streams 

線程2啓動和線程設置它是私有m_so:

void exec2b() // thread 2 entry 
{ 
    m_now = Clock_t::now(); 

    m_so = &m_ssMagic; // m_so points to m_ssMagic 

    // ... 

    m_ssMagic << " execDuration = " << m_ssDuration.str() 
       << " (b) " << std::endl; 
} // exec2b (void) 

雖然線程1使用的std ::法院和線程2使用m_ssMagic, '主'(線程0 )只是等待連接。

連接的座標線程完成,通常大約在同一時間。 Main(線程0)然後cout的m_ssMagic內容。

//... 
// main thread context: 
case 2: // one parameter: 2 threads each runs 1/2 of tests 
{ // use two new instances 
    T431_t t431a(MaxDualCoreMS); // lower test sequence 
    T431_t t431b(MaxDualCoreMS); // upper test sequence 

    // 2 additional threads started here 
    std::thread tA (&T431_t::exec2a, &t431a); 
    std::thread tB (&T431_t::exec2b, &t431b); 

    // 2 join's - thread main (0) waits for each to complete 
    tA.join(); 
    tB.join(); 

    // tA outputs directly to std::cout 
    // tB captured output to T431_t::m_ssMagic. 

    // both thread 1 and 2 have completed, so ok to: 
    std::cout << t431b.ssMagicShow() << std::endl; 

    retVal = 0; 
} break; 

是完整的,這裏是

std::string ssMagicShow() { return (m_ssMagic.str()); } 

摘要

我第一次寫的單線程應用程序。得到這個工作後,我搜索了一個'簡單'的方式來使用我的桌面上的第二個核心。

作爲我的第一個重構的一部分,我a)添加了「std :: ostream m_so」初始化爲& std :: cout,並且b)找到了std :: cout的所有用法。其中大部分我簡單替換爲「* m_so」。然後我c)證實我沒有破壞單線程解決方案。很容易,並嘗試第一次。

後續工作實現了命令行'雙線程'選項。

我認爲這個方法將適用於我的下一個桌面,當預算允許時。


,並從OOP的角度來看,這方面的努力工作,因爲的std :: ostream的是在這兩種性病::法院和std :: stringstream的的類層次結構。因此

"std::cout is-a std::ostream", 

"std::stringstream is-a std::ostream". 

所以m_so可以指向派生類的實例,並提供虛擬方法的ostream接入'要麼目的地。