2017-08-04 9 views
0

ostreamが正確であることを理解することには基本的な問題があります。私はそれが出力ストリームの基本クラスであることを知っていますが、私はそれを使用する理由と、単にstd :: coutと言うのではなく、なぜそれを使用するのか、あまり気にしません。 ここでは、pop()関数でスタックという名前の新しいクラスを作成する必要があるこの例があります(C++ですでに提供されているクラスと同じです)。ostreamを関数の引数として使用する

ここで、list_nodeは、キー(整数)と次の整数を指すインターレーターの2つの要素で構成される構造体です。 (すでに与えられた)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'の別名ではありません。 Formerは基本クラスであり、2番目は指​​定されていない型のオブジェクトです。第二に、あなたが何を求めているのかは不明です。 – SergeyA

+0

このメソッドはスタック内で定義されていますか? 'top_node'はスタッククラスのメンバですか?あなたが何を求めているかは本当に不明です。それは欠けている文脈がたくさんあるように見える。 –

+0

[mcve] –

答えて

0

どうしてそうした方が良いのですか?

私はあなたの質問には分かりませんが、それが良い方法であるかどうかはわかりません。

多分、その意図は柔軟性のためです。ここに私のアプリのライブラリーからの例です:


私はostreamに私が自明「-m_soポイント」にレポートを配信するために、その属性を使用することができます

class T431_t 
{ 
    // ... 
    std::ostream*  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; 
    // ... 
} 

クラスコンストラクタ(ctor)には、m_soとstd :: coutのデフォルト割り当てがあります。ユーザーがデスクトップの両方のプロセッサを使用して1/2程度の時間でアプリケーションを実行するためのコマンドラインオプションでデュアルスレッド処理オプションを選択すると、レポートになることができ

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

2つの独立した出力ストリームを(ユーザ画面上で)絡み合わせることができれば、読みにくい。したがって、スレッド2によって実行されるオブジェクトインスタンスでは、m_soは何か異なるものに設定されます。

次のデータ属性は、後でstd :: coutにストリーミングするためにスレッド2の出力をキャプチャして保持します。

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 :: coutのを使用し、スレッド2がm_ssMagicを使用していますが、 'メイン'(スレッド0 )は単にジョインを待つだけです。

通常、ジョインはスレッドの完了を調整します。通常、ほぼ同じ時刻です。メイン(スレッド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()); } 

概要

がある私は、最初のシングルスレッドアプリケーションを書きました。その作業をした後、私はデスクトップ上で2番目のコアを利用するための「シンプルな」方法を探しました。

最初のリファクタの一環として、私は& std :: coutに初期化された "std :: ostream m_so"を追加し、b)std :: coutのすべての使用法を見つけました。これらのほとんどは単に「* m_so」に置き換えられました。私はその後、c)シングルスレッドソリューションを壊していないことを確認しました。非常に簡単で、最初の試みをしました。

その後の作業では、コマンドライン 'dual-thread'オプションが実装されました。

このアプローチは、予算が許せば私の次のデスクトップにも当てはまると思います。


そして、OOPの観点からはstd :: ostreamには、は、はstd :: coutのとstdの両方のクラス階層::にstringstreamにあるので、この努力は動作します。したがって

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

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

だからm_soは、派生クラスのいずれかのインスタンスを指し、そして先のいずれかに仮想メソッド「のostreamアクセス」を提供することができます。

関連する問題