J'ai trouvé le code suivant dans un fichier d'en-tête et la classe "BOOT" est définie dans un autre fichier d'en-tête.
class BOOT* boot(void);
Cela ressemble à une déclaration de fonction, mais cela commence par class .
4 Réponses :
Que signifie «class classname * funcname (void)» en C ++?
C'est une déclaration de fonction.
Cela ressemble à une déclaration de fonction, mais cela commence par "class".
class classname* est le type de retour de la fonction. class classname est un spécificateur de type élaboré.
C'est la même chose:
class BOOT; BOOT* boot(void);
C'est donc un pointeur vers la class BOOT , mais avec une déclaration de la classe également. La classe n'a pas besoin d'être définie à ce stade.
Il s'agit d'un spécificateur de type élaboré:
Les spécificateurs de type élaborés peuvent être utilisés pour faire référence à un nom de classe précédemment déclaré (classe, structure ou union) ou à un nom d'énumération précédemment déclaré même si le nom était masqué par une déclaration de non-type. Ils peuvent également être utilisés pour déclarer de nouveaux noms de classe.
https://en.cppreference.com/w/cpp/language/elaborated_type_specifier
Prenant des réponses d'Artefacto et de dfrib parce que cela l'amène au point: c'est équivalent à:
struct Node {
struct Node* Next; // OK: lookup of Node finds the injected-class-name
struct Data* Data; // OK: declares type Data at global scope
// and also declares the data member Data
friend class ::List; // error: cannot introduce a qualified name
enum Kind* kind; // error: cannot introduce an enum
};
Data* p; // OK: struct Data has been declared
Dans votre exemple, il fait essentiellement une déclaration avant de la classe BOOT si elle n'est pas encore connue. Voir cet exemple struct Data* Data; de la même page:
class BOOT; BOOT* boot(void);
Comparez et contrastez avec: class BOOT; using BOOT = int; BOOT* boot(void);
Est-ce utile au-delà de l'enregistrement d'une ligne? Je serais également confus par cette syntaxe et préférerais les deux déclarations séparément pour plus de lisibilité.
@ahota: La documentation dit: "Les spécificateurs de type élaborés peuvent être utilisés pour faire référence à un nom de classe précédemment déclaré (classe, structure ou union) ou à un nom d'énumération précédemment déclaré même si le nom était masqué par une déclaration de non-type . " (voir stackoverflow.com/questions/57865891 pour plus de détails) Il a sa place. Personnellement, je préfère être plus explicite, c'est-à-dire que j'éviterais la syntaxe, si elle n'est pas nécessaire. Toutefois, c'est une question de préférence personnelle.
En C ++ , vous pouvez déclarer un type de fonction dont le type de retour contient un type de classe qui est définie ailleurs, aussi longtemps que vous déclarez soit explicitement en avant le type de classe avant la déclaration de fonction:
elaborated-type-specifier:
class-key [...]
[...]
mais vous pouvez également placer la déclaration forward en ligne dans la déclaration de fonction:
template<typename T>
struct Identity { using type = T; };
using IdentityBoot = Identity<struct BOOT>;
// ^^^^^^^^^^^ also a forward declaration
// OK
BOOT* boot();
// OK
typename IdentityBoot::type* another_boot();
C'est l'un des endroits où, peut-être de manière quelque peu inattendue, les déclarations anticipées peuvent être utilisées. Un autre exemple est comme dans la liste d'arguments de modèle pour un paramètre de modèle de type:
class BOOT* boot();
Formellement, c'est un spécificateur de type élaboré , régi par [dcl.type.elab] ,
class BOOT; BOOT* boot();
qui est utilisé pour, selon [class] / 1 , créer un nom de classe qui est introduit dans la portée où le spécificateur de type élaboré est utilisé [c'est moi qui souligne ]:
Une classe est un type. Son nom devient un nom de classe ([class.name]) dans sa portée. [...]
Les spécificateurs de classe et les spécificateurs de type élaboré sont utilisés pour créer des noms de classe .
C'est une fonctionnalité héritée de C. En C, vous devez ajouter le mot clé
struct/unionchaque fois que vous en faites référence. En C ++, cela est facultatif. Ainsi, laclass BOOL=BOOLEn C ++, cela vous permet uniquement de déclarer un type de fonction qui renvoie un pointeur d'un type de classe (éventuellement incomplet), mais sans avoir à déclarer en avant le type de classe
BOOTavant la déclaration. Une alternative serait laclass BOOT; // forward declarationsuivie deBOOT* boot();.,@king_nak Ils ne sont pas strictement identiques, la
class BOOLfonctionne également comme une déclaration avant ici.Comparez avec les constructions de
typedef structancienne et donnez un tourbillon à votre cerveau;)@king_nak Un autre avantage de dire "class BOOL" est que - comme le souligne la citation cppreference citée par René - c'est valable même si quelqu'un a précédemment déclaré un typedef BOOT (sans rapport avec lui).
Cela a déjà été répondu ici: stackoverflow.com/questions/28007165/...