Question

Je veux dire autre chose que l’utiliser quand cela est nécessaire pour les fonctions, les classes, si, pendant que, changez, essayez-attrapez.

Je ne savais pas que cela pourrait être fait comme jusqu’à ce que je voie cette question SO .

Dans le lien ci-dessus, Eli a déclaré qu '"ils l'utilisent pour replier leur code dans des sections logiques qui ne font pas partie d'une fonction, d'une classe, d'une boucle, etc. qui seraient normalement repliées."

Quels sont les autres usages autres que ceux mentionnés?

Est-ce une bonne idée d'utiliser des accolades pour limiter la portée de vos variables et élargir celle-ci uniquement si nécessaire (en travaillant sur un "besoin d'accès")? Ou est-ce réellement idiot?

Pourquoi ne pas utiliser des étendues simplement pour pouvoir utiliser les mêmes noms de variable dans différentes portées mais dans le même plus grand? Ou est-ce une meilleure pratique de réutiliser la même variable (si vous voulez utiliser le même nom de variable) et d’économiser sur la désallocation et l’allocation (je pense que certains compilateurs peuvent optimiser cela?)? Ou vaut-il mieux utiliser différents noms de variable?

Était-ce utile?

La solution

Je le fais si j'utilise une ressource que je souhaite libérer à un moment précis, par exemple:

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...
}

Autres conseils

Je ne voudrais pas utiliser d'accolades pour cette raison pour deux raisons.

  1. Si votre fonction particulière est suffisamment importante pour que vous deviez effectuer différentes astuces de cadrage, divisez-la en plusieurs sous-fonctions.

  2. L'introduction d'accolades permettant de définir des portées pour réutiliser les noms de variables ne fera que créer de la confusion et des problèmes de code.

Seulement mes 2 centimes, mais j'ai vu beaucoup de choses de ce genre dans d'autres documents sur les meilleures pratiques.

Le "plus commun" " non standard " L’utilisation de la portée que j’utilise régulièrement consiste à utiliser un mutex à portée.

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
}

Cela présente de nombreux avantages, mais le plus important est que le verrou sera toujours nettoyé, même si une exception est générée dans le code protégé.

C ++ :

Parfois, vous avez besoin d'introduire un niveau supplémentaire d'accolade pour réutiliser les noms de variables lorsqu'il est logique de le faire:

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

Le code ci-dessus ne compile pas. Vous devez le faire:

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

Comme d’autres l'ont déjà dit, l'utilisation la plus courante consiste à s'assurer que les destructeurs s'exécutent quand vous le souhaitez. C'est aussi pratique pour clarifier un peu le code spécifique à la plate-forme:

#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
    }

Le code créé pour Windows ne voit pas le si, seulement les accolades. Ceci est beaucoup plus clair que:

#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

Cela peut être une aubaine pour les générateurs de code. Supposons que vous ayez un compilateur Embedded SQL (ESQL); il peut être utile de convertir une instruction SQL en un bloc de code nécessitant des variables locales. En utilisant un bloc, il peut réutiliser des noms de variables fixes, sans avoir à créer toutes les variables avec des noms distincts. Certes, ce n’est pas trop difficile, mais c’est plus difficile que nécessaire.

Comme d'autres l'ont déjà dit, cela est assez courant en C ++ en raison du tout-puissant langage / modèle RAII (l'acquisition des ressources est l'initialisation).

Pour les programmeurs Java (et peut-être C #, je ne sais pas), il s'agira d'un concept étranger car les objets basés sur les segments de mémoire et le GC tuent RAII. IMHO, pouvoir mettre des objets sur la pile est le plus grand avantage du C ++ par rapport à Java et rend le code C ++ bien écrit bien plus propre que le code Java bien écrit.

Je ne l'utilise que lorsque j'ai besoin de libérer quelque chose par le biais de RAII et même dans ce cas seulement quand il devrait l'être le plus tôt possible (en libérant un verrou, par exemple).

Programmation en Java J'ai souvent voulu limiter le champ d'application d'une méthode, mais il ne m'est jamais venu à l'idée d'utiliser une étiquette. Comme je mets en majuscule mes étiquettes lorsque je les utilise comme cible d’une pause, l’utilisation d’un bloc à casse mixte, comme vous l’avez suggéré, est exactement ce que j’ai voulu à cette occasion.

Souvent, les blocs de code sont trop courts pour être divisés en une petite méthode, et souvent dans une méthode framework (telle que startup () ou shutdown ()), il est préférable de conserver le code ensemble dans une seule méthode.

Personnellement, je déteste les accolades flottantes / flottantes (bien que ce soit parce que nous sommes un magasin indent de type bannière strict) et que je déteste le marqueur de commentaire:

// 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

Nous avons envisagé d'utiliser & if; if (true) {" parce que la spécification Java spécifie spécifiquement que ceux-ci seront optimisés lors de la compilation (de même que tout le contenu d’un if (false) - c’est une fonctionnalité de débogage), mais j’ai détesté cela dans les rares endroits où je l’ai essayée.

Donc, je pense que votre idée est bonne, pas du tout stupide. J'ai toujours pensé que j'étais le seul à vouloir le faire.

Oui, j’utilise cette technique à cause de RAII. J'utilise également cette technique en clair C car elle rapproche les variables. Bien sûr, je devrais penser à casser encore plus les fonctions.

Une chose que je fais et qui est probablement controversée sur le plan stylistique est de placer l'accolade initiale sur la ligne de la déclaration ou de formuler un commentaire à ce sujet. Je souhaite réduire la quantité d'espace vertical gaspillé. Ceci est basé sur la recommandation de Google C ++ Style Guide. .

/// 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);
  }
}

Je suis d'accord avec agartzke. Si vous estimez que vous devez segmenter des blocs de code logique plus volumineux pour des raisons de lisibilité, envisagez de procéder à un refactoring afin de nettoyer les membres occupés et encombrés.

Cela a sa place, mais je ne pense pas que faire en sorte que $ foo puisse être une variable ici et une variable différente , dans la même fonction ou une autre portée (logique plutôt que lexicale) est une bonne idée. Même si le compilateur le comprend parfaitement, il semble trop probable que les humains qui essaient de lire le code puissent avoir du mal à lire le code.

La société dans laquelle je travaille a une politique d'analyse statique qui permet de conserver les déclarations de variables locales au début d'une fonction. Plusieurs fois, l'utilisation est plusieurs lignes après la première ligne d'une fonction, je ne peux donc pas voir la déclaration et la première référence en même temps à l'écran. Ce que je fais pour "contourner" la stratégie est de conserver la déclaration près de la référence, tout en fournissant une portée supplémentaire en utilisant des accolades. Cependant, il augmente l’indentation, et certains diront que cela rend le code plus laid.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top