Go to the first, previous, next, last section, table of contents.

7.2 Class Member Specifications

The member-seq in a class specification specifies both data and function members of the class. The syntax for the member-seq is as follows. (The syntax for a constant-expression is exactly as in C++.)

member-seq ::= [ member-seq ] member-declaration
        | [ member-seq ] access-specifier :
        | [ member-seq ] larch-cpp-clause

larch-cpp-clause ::= uses-clause
        | simulates-clause
        | depends-clause
        | represents-clause
        | invariant-clause
        | constraint-clause

member-declaration ::= function-definition
        | [ decl-specifier-seq ] [ member-declarator-list ] ; [ fun-spec-body ]
        | [ decl-qualifier-seq ] ctor-declarator ; [ fun-spec-body ]
        | [ decl-qualifier-seq ] special-function-declarator ; [ fun-spec-body ]
        | [ :: ] nested-name-specifier [ template ] unqualified-id
        | using-declaration
        | template-declaration
        | spec-decl
        | refinement-member-decl

member-declarator-list ::= member-declarator [ , member-declarator ] ...

member-declarator ::= declarator [ constant-initializer ]
       | [ identifier ] : constant-expression

constant-initializer ::= = constant-expression

access-specifier ::= public | protected | private

A member-seq thus consists of member-declarations, uses-clauses, simulates-clauses, depends-clauses, represents-clauses, invariant-clauses, constraint-clauses, and access-specifiers. As in C++, the access-specifiers give the accessibility of the members specified following them up to the next access-specifier. Recall that the default access-specifier, if none is explicitly given, is private. Since usually one specifies public function members, it is important to remember to give an access-specifier explicitly. Members specified with a given access must be implemented by definitions with that access. Besides the usual specification of public members, one may also specify protected and private members in Larch/C++. See section 10.3 Specifying Protected and Private Interfaces for when and how to specify protected and private members.

In a protected or private interface specification, some data members that are not visible in the public interface may need to be modified. To allow this modification to take place, one uses a depends-clause. See section 7.6 The Depends Clause for details on dependencies.

Invariants and constraints may also be specified anywhere a member may be specified; this is to facilitate invariants about data members, which can only be stated after such members are declared. See section 7.3 Class Invariants for details on invariants. See section 7.4 History Constraints for details on constraints.

A member-declaration can take several forms. The first implements function members. The second, with the syntax

[ decl-specifier-seq ] [ member-declarator-list ] ; [ fun-spec-body ]

is the most common in Larch/C++. It is commonly used to declare and specify function members. See section 6 Function Specifications for the syntax and semantics of a function-spec-body that is not specific to classes. It can also be used to simply declare function members, without giving a specification, to declare data members, to grant friendship, and to adjust access. Such a declaration is implemented by a matching declaration in the code, unless it is a spec-decl. See section 7.11 Specifying Exposed Data Members for cases when you might want to use declarations that are not spec-decls to specify data members in a class. See section 7.12 Specifying Friends for when and how to grant friendship. However, for simple class specifications, it is usual to only use spec-decls and to specify function members. To adjust access, the decl-specifier-seq are omitted and the member-declarator-list consists of a id-expression which contains :: (see section 5.4 Declarators for the syntax). This adjusts the access to names inherited from base classes (see section 7.8 Specifying Derived Classes), and has the same meaning as in C++. See section 11.4 of [Ellis-Stroustrup90] for details.

The third form of a member-declaration is used to declare, and optionally specify, a constructor for a class. See section 7.2.1 Constructors for more discussion and examples.

The fourth form is a using-declaration. This can also be used to adjust access to inherited members. See Section r.3.1 of [Stroustrup95] for details. See section 5.5 C++ Namespace and Using Declarations for the syntax of using-declaration.

See section 9.1 Ghost Variables for the syntax and semantics of spec-decl.

See section 10.6 Nested Refinement for the syntax and semantics of a refinement-member-decl.

In the syntax of a member-declarator, the use of a colon (:) followed by a constant-expression is for specifying a C++ bit-field (see section 9.6 of [Ellis-Stroustrup90]). It would only be used in a class specification to record a detailed design decision.

Inside the specification of a member function, data members are considered to be in scope. Thus they do not need to be made explicitly made visible with an extern declaration (see section 6.7 Global Variables), as was done in early versions of Larch/C++.

If you specify the abstract values of a class explicitly, by giving a LSL trait that has a sort with the same name as the class, then you may not be able to refer to data members through self. For example, if you specify a class Counter with a public data member count, but you also explicitly use a trait that describes the abstract values of Counter instead of letting Larch/C++ automatically construct the trait for you, then you can only write self^.count in a member function specification if your trait has a trait function __.count defined on the abstract values. On the other hand, you could still use an invariant to specify a relationship between your data member and parts of the abstract values you specified. See section 7.11 Specifying Exposed Data Members for an example.

The subsections below describe some details of various member specifications.

Go to the first, previous, next, last section, table of contents.