Domanda

Intendo altro che usarlo quando richiesto per funzioni, classi, se, mentre, cambia, prova a catturare.

Non sapevo che potesse essere fatto come questo fino a quando ho visto questa domanda SO .

Nel link sopra, Eli ha detto che " Lo usano per piegare il loro codice in sezioni logiche che non rientrano in una funzione, classe, loop, ecc. che normalmente verrebbero piegate. "

Quali altri usi ci sono oltre a quelli menzionati?

È una buona idea usare le parentesi graffe per limitare l'ambito delle variabili ed espandere l'ambito solo se necessario (lavorando su una base "necessità di accedere")? O è davvero sciocco?

Che ne dici di usare gli ambiti solo per poter usare gli stessi nomi di variabili in ambiti diversi ma nello stesso ambito più grande? Oppure è una buona pratica riutilizzare la stessa variabile (se si desidera utilizzare lo stesso nome di variabile) e risparmiare sulla deallocazione e allocazione (penso che alcuni compilatori possano ottimizzare su questo?)? O è meglio usare nomi di variabili diverse del tutto?

È stato utile?

Soluzione

Lo faccio se sto usando una risorsa che voglio liberare in un momento specifico, ad esempio:

void myfunction()
{
  {
  // Open serial port
     SerialPort port("COM1", 9600);
     port.doTransfer(data);
  } // Serial port gets closed here.

  for(int i = 0; i < data.size(); i++)
     doProcessData(data[i]);
  etc...
}

Altri suggerimenti

Non userei le parentesi graffe per quello scopo per un paio di ragioni.

  1. Se la tua particolare funzione è abbastanza grande da dover eseguire vari trucchi di scoping, forse suddividere la funzione in sotto-funzioni più piccole.

  2. L'introduzione di parentesi graffe per l'ambito scoping per riutilizzare i nomi delle variabili non farà che generare confusione e problemi nel codice.

Solo i miei 2 centesimi, ma ho visto molti di questi tipi di cose in altri materiali di buone pratiche.

Il più comune "non standard" l'uso di scoping che uso regolarmente è di utilizzare un mutex con ambito.

void MyClass::Somefun()
{
    //do some stuff
    {
        // example imlementation that has a mutex passed into a lock object:
        scopedMutex lockObject(m_mutex); 

        // protected code here

    } // mutex is unlocked here
    // more code here
}

Ciò ha molti vantaggi, ma il più importante è che il blocco verrà sempre ripulito, anche se viene generata un'eccezione nel codice protetto.

C ++ :

A volte è necessario introdurre un ulteriore livello di parentesi graffa per riutilizzare i nomi delle variabili quando ha senso farlo:

switch (x) {
    case 0:
        int i = 0;
        foo(i);
        break;
    case 1:
        int i = 1;
        bar(i);
        break;
}

Il codice sopra non viene compilato. Devi farlo:

switch (x) {
    case 0:
        {
            int i = 0;
            foo(i);
        }
        break;
    case 1:
        {
            int i = 1;
            bar(i);
        }
        break;
}

L'uso più comune, come altri hanno già detto, è assicurarsi che i distruttori vengano eseguiti quando lo si desidera. È anche utile per rendere un po 'più chiaro il codice specifico della piattaforma:

#if defined( UNIX )
    if( some unix-specific condition )
#endif
    {
        // This code should always run on Windows but 
        // only if the above condition holds on unix
    }

Il codice creato per Windows non vede se, solo le parentesi graffe. Questo è molto più chiaro di:

#if defined( UNIX )
    if( some unix-specific condition ) {
#endif
        // This code should always run on Windows but 
        // only if the above condition holds on unix
#if defined( UNIX )
    }
#endif

Può essere un vantaggio per i generatori di codice. Supponiamo di avere un compilatore SQL incorporato (ESQL); potrebbe voler convertire un'istruzione SQL in un blocco di codice che necessita di variabili locali. Utilizzando un blocco, può riutilizzare più volte nomi di variabili fisse, anziché dover creare tutte le variabili con nomi separati. Certo, non è troppo difficile, ma è più difficile del necessario.

Come altri hanno già detto, questo è abbastanza comune in C ++ a causa dell'onnipotente linguaggio / modello RAII (acquisizione delle risorse è inizializzazione).

Per i programmatori Java (e forse C #, non lo so) questo sarà un concetto estraneo perché oggetti basati su heap e GC uccide RAII. IMHO, essere in grado di mettere gli oggetti nello stack è il più grande vantaggio di C ++ su Java e rende il codice C ++ ben scritto MOLTO più pulito del codice Java ben scritto.

Lo uso solo quando devo rilasciare qualcosa tramite RAII e anche solo quando dovrebbe essere rilasciato il prima possibile (rilasciando un lucchetto per esempio).

Programmazione in Java Ho spesso voluto limitare l'ambito all'interno di un metodo, ma non mi è mai venuto in mente di usare un'etichetta. Dal momento che ho usato le lettere maiuscole quando le ho usate come destinazione di un'interruzione, usare un blocco etichettato con custodia mista come hai suggerito è proprio quello che volevo in queste occasioni.

Spesso i blocchi di codice sono troppo brevi per essere suddivisi in un metodo piccolo, e spesso il codice in un metodo framework (come startup () o shutdown ()) ed è effettivamente meglio mantenere il codice insieme in un metodo.

Personalmente odio le semplici parentesi graffe galleggianti / pendenti (anche se questo è perché siamo un rigoroso rientro in stile banner), e odio il marcatore di commento:

// yuk!
some code
{
scoped code
}
more code

// also yuk!
some code
/* do xyz */ {
    scoped code
    }
some more code

// this I like
some code
DoXyz: {
    scoped code
    }
some more code

Abbiamo considerato l'utilizzo di " if (true) {" perché le specifiche Java dicono specificamente che queste saranno ottimizzate via nella compilazione (così come l'intero contenuto di un if (false) - è una funzione di debug), ma odiavo che nei pochi posti in cui l'ho provato.

Quindi penso che la tua idea sia valida, per niente sciocca. Ho sempre pensato di essere l'unico a volerlo fare.

Sì, utilizzo questa tecnica a causa di RAII. Uso questa tecnica anche in C poiché avvicina le variabili. Certo, dovrei pensare di interrompere ancora di più le funzioni.

Una cosa che faccio, probabilmente stilisticamente controversa, è mettere la parentesi graffa aperta sulla riga della dichiarazione o inserire un commento proprio su di essa. Voglio ridurre la quantità di spazio verticale sprecato. Questo si basa sulla raccomandazione della Guida allo stile di Google C ++. .

/// c++ code
/// references to boost::test
BOOST_TEST_CASE( curly_brace )
{
  // init
  MyClass instance_to_test( "initial", TestCase::STUFF ); {
    instance_to_test.permutate(42u);
    instance_to_test.rotate_left_face();
    instance_to_test.top_gun();
  }
  { // test check
    const uint8_t kEXP_FAP_BOOST = 240u;
    BOOST_CHECK_EQUAL( instance_to_test.get_fap_boost(), kEXP_FAP_BOOST);
  }
}

Sono d'accordo con Agartzke. Se ritieni di dover segmentare blocchi di codice logici più grandi per la leggibilità, dovresti prendere in considerazione il refactoring per ripulire i membri occupati e disordinati.

Ha il suo posto, ma non penso che farlo in modo che $ foo possa essere una variabile qui e una diversa variabile , all'interno della stessa funzione o un altro ambito (logico, piuttosto che lessicale) è una buona idea. Anche se il compilatore può capirlo perfettamente, sembra troppo difficile rendere la vita difficile agli umani che cercano di leggere il codice.

La società a cui sto lavorando ha una politica di analisi statica per mantenere le dichiarazioni delle variabili locali vicino all'inizio di una funzione. Molte volte, l'utilizzo è composto da molte righe dopo la prima riga di una funzione, quindi non riesco a vedere sullo schermo la dichiarazione e il primo riferimento contemporaneamente. Quello che faccio per "eludere" la politica è di mantenere la dichiarazione vicino al riferimento, ma fornire ulteriore portata usando parentesi graffe. Tuttavia, aumenta il rientro e alcuni potrebbero obiettare che rende il codice più brutto.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top