Here’s an example which illustrates some C++ class syntactic symbols:
1: class Bass 2: : public Guitar, 3: public Amplifiable 4: { 5: public: 6: Bass() 7: : eString( new BassString( 0.105 )), 8: aString( new BassString( 0.085 )), 9: dString( new BassString( 0.065 )), 10: gString( new BassString( 0.045 )) 11: { 12: eString.tune( 'E' ); 13: aString.tune( 'A' ); 14: dString.tune( 'D' ); 15: gString.tune( 'G' ); 16: } 17: friend class Luthier; 18: };
As in the previous example, line 1 has the topmost-intro
syntax.
Here however, the brace that opens a C++ class definition on line 4 is
assigned the class-open
syntax. Note that in C++, classes,
structs, and unions are essentially equivalent syntactically (and are
very similar semantically), so replacing the class
keyword in the
example above with struct
or union
would still result in a
syntax of class-open
for line 4 37.
Similarly, line 18 is assigned class-close
syntax.
Line 2 introduces the inheritance list for the class so it is assigned
the inher-intro
syntax, and line 3, which continues the
inheritance list is given inher-cont
syntax.
Hitting C-c C-s on line 5 shows the following analysis:
((inclass 58) (access-label 58))
The primary syntactic symbol for this line is access-label
as
this is a label keyword that specifies access protection in C++. However,
because this line is also a top-level construct inside a class
definition, the analysis actually shows two syntactic symbols. The
other syntactic symbol assigned to this line is inclass
.
Similarly, line 6 is given both inclass
and topmost-intro
syntax:
((inclass 58) (topmost-intro 60))
Line 7 introduces a C++ member initialization list and as such is given
member-init-intro
syntax. Note that in this case it is
not assigned inclass
since this is not considered a
top-level construct. Lines 8 through 10 are all assigned
member-init-cont
since they continue the member initialization
list started on line 7.
Line 11’s analysis is a bit more complicated:
((inclass 58) (inline-open))
This line is assigned a syntax of both inline-open
and
inclass
because it opens an in-class C++ inline method
definition. This is distinct from, but related to, the C++ notion of an
inline function in that its definition occurs inside an enclosing class
definition, which in C++ implies that the function should be inlined.
However, if the definition of the Bass
constructor appeared
outside the class definition, the construct would be given the
defun-open
syntax, even if the keyword inline
appeared
before the method name, as in:
1: class Bass 2: : public Guitar, 3: public Amplifiable 4: { 5: public: 6: Bass(); 7: }; 8: 9: inline 10: Bass::Bass() 11: : eString( new BassString( 0.105 )), 12: aString( new BassString( 0.085 )), 13: dString( new BassString( 0.065 )), 14: gString( new BassString( 0.045 )) 15: { 16: eString.tune( 'E' ); 17: aString.tune( 'A' ); 18: dString.tune( 'D' ); 19: gString.tune( 'G' ); 20: }
Returning to the previous example, line 16 is given inline-close
syntax, while line 12 is given defun-block-open
syntax, and lines
13 through 15 are all given statement
syntax. Line 17 is
interesting in that its syntactic analysis list contains three
elements:
((inclass 58) (topmost-intro 380) (friend))
The friend
and inline-open
syntactic symbols are
modifiers that do not have anchor positions.
Template definitions introduce yet another syntactic symbol:
1: ThingManager <int, 2: Framework::Callback *, 3: Mutex> framework_callbacks;
Here, line 1 is analyzed as a topmost-intro
, but lines 2 and 3
are both analyzed as template-args-cont
lines.
This is the case even
for C and Objective-C. For consistency, structs in all supported
languages are syntactically equivalent to classes. Note however that
the keyword class
is meaningless in C and Objective-C.