Pourquoi est-il préférable de le faire comme ils l'ont fait?
Je ne suis pas sûr de votre question, et je ne suis pas sûr que ce soit un meilleur moyen. Peut-être que l'intention était pour la flexibilité. Voici l'exemple de ma bibliothèque d'applications:
Quand je déclare un attribut de données comme un ostream
class T431_t
{
// ...
std::ostream* m_so;
// ...
je peux trivialement utiliser cet attribut pour fournir un rapport « où-m_so points » . Dans cette application, il existe plusieurs exemples de * mso < < ... en cours d'utilisation. Voici l'exemple principal.
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;
// ...
}
Notez que dans le constructeur de classe (cteur), il y a une affectation par défaut pour m_so à std :: Cout.
T431_t(uint64_t maxDuration = MaxSingleCoreMS) :
// ..
m_so (&std::cout), // ctor init - default
// ..
{
// ...
Lorsque l'utilisateur sélectionne l'option de traitement à double fil, qui est une option de ligne de commande pour exécuter l'application dans environ 1/2 du temps en utilisant les deux processeurs de mon bureau, les rapports peuvent devenir difficile à lire si j'autorise l'entrelacement des deux flux de sortie indépendants (sur l'écran de l'utilisateur). Ainsi, dans l'instance d'objet exécutée par le thread 2, m_so est défini quelque chose de différent. L'attribut de données suivant capture et conserve la sortie du thread 2 pour diffusion ultérieure vers std :: cout.
std::stringstream m_ssMagic; // dual threads use separate out streams
Discussion 2 est lancé et le fil fixe, il est m_so privé:
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)
Alors que le thread 1 utilise std :: Cout, et le fil 2 utilise m_ssMagic, 'main' (fil 0) attend simplement les jointures.
Les jointures coordonnent la fin du fil, généralement à peu près au même moment. Main (thread 0) puis cout le contenu de 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;
Pour être complet, voici
std::string ssMagicShow() { return (m_ssMagic.str()); }
Résumé
j'ai écrit l'application de fil unique en premier. Après avoir obtenu ce travail, j'ai cherché un moyen «simple» d'utiliser le deuxième noyau sur mon bureau.
Dans le cadre de mon premier refactor, j'ai) ajouté "std :: ostream m_so" initialisé à & std :: cout, et b) trouvé toutes les utilisations de std :: cout. La plupart d'entre eux j'ai simplement remplacé par "* m_so". J'ai ensuite c) confirmé que je n'avais pas cassé la solution à un seul fil. Assez facile, et a travaillé le premier essai.
L'effort suivant a implémenté l'option 'dual-thread' de la ligne de commande.
Je pense que cette approche s'appliquera à mon bureau suivant, lorsque le budget le permet.
Et d'un point de vue de la POO, cet effort fonctionne parce que std :: ostream est dans la hiérarchie des classes des deux std :: et std :: Cout stringstream. Ainsi
"std::cout is-a std::ostream",
et
"std::stringstream is-a std::ostream".
Ainsi m_so peut indiquer par exemple de l'une classe dérivée, et fournir méthode virtuelle « ostream accès » à une ou l'autre destination.
Tout d'abord, 'std :: ostream' n'est certainement pas ** un autre nom pour' std :: cout'. Former est une classe de base, la seconde est un objet de type non spécifié. Deuxièmement, on ne sait pas ce que vous demandez. – SergeyA
Cette méthode est-elle définie à l'intérieur de la pile? Est-ce que 'top_node' est un membre de la classe de pile? Ce n'est vraiment pas clair ce que vous demandez; On dirait qu'il y a beaucoup de contexte manquant. –
Vous devriez fournir un [mcve] –