Classes are user-defined types, defined by class-specifier, which appears indecl-specifier-seq of thedeclaration syntax.
The class specifier has the following syntax:
|
class-keyattr (optional)class-head-nameclass-property-specs (optional)base-clause (optional)
{ member-specification} | (1) | |
|
class-keyattr (optional)base-clause (optional)
{ member-specification} | (2) | |
|
1) Named class definition
2) Unnamed class definition
class-key | - | one ofclass,struct andunion. The keywordsclass andstruct are identical except for the defaultmember access and the defaultbase class access. If it isunion, the declaration introduces aunion type. |
attr | - | (since C++11) any number ofattributes, may includealignas specifier |
class-head-name | - | the name of the class that's being defined, optionallyqualified |
class-property-specs | - | A list of the following specifiers, each specifier is allowed at most once in each sequence.Specifier | Effect |
---|
final (since C++11) | Specifies that the classcannot be derived | trivially_relocatable_if_eligible (since C++26) | Marks the class to be trivially relocatable if eligible | replaceable_if_eligible (since C++26) | Marks the class to be replaceable if eligible |
|
base-clause | - | list of one or more base classes and the model of inheritance used for each (seederived class) |
member-specification | - | list of access specifiers, member object and member function declarations and definitions (see below) |
[edit]Forward declaration
A declaration of the following form
Declares a class type which will be defined later in this scope. Until the definition appears, this class name hasincomplete type. This allows classes that refer to each other:
class Vector;// forward declaration class Matrix{// ...friend Vector operator*(const Matrix&,const Vector&);}; class Vector{// ...friend Vector operator*(const Matrix&,const Vector&);};
and if a particular source file only uses pointers and references to the class, this makes it possible to reduce#include dependencies:
// In MyStruct.h#include <iosfwd> // contains forward declaration of std::ostream struct MyStruct{int value;friendstd::ostream& operator<<(std::ostream& os,const S& s);// definition provided in MyStruct.cpp file which uses #include <ostream>};
If forward declaration appears in local scope, ithides previously declared class, variable, function, and all other declarations of the same name that may appear in enclosing scopes:
struct s{int a;};struct s;// does nothing (s already defined in this scope) void g(){struct s;// forward declaration of a new, local struct "s"// this hides global struct s until the end of this block s* p;// pointer to local struct s struct s{char* p;};// definitions of the local struct s}
Note that a new class name may also be introduced by anelaborated type specifier which appears as part of another declaration, but only ifname lookup can't find a previously declared class with the same name.
class U; namespace ns{class Y f(class T p);// declares function ns::f and declares ns::T and ns::Y class U f();// U refers to ::U // can use pointers and references to T and Y Y* p; T* q;}
[edit]Member specification
The member specification, or thebody of a class definition, is a brace-enclosed sequence of any number of the following:
1) Member declarations of the form
|
attr (optional)decl-specifier-seq (optional)member-declarator-list (optional); | | |
|
This declaration may declarestatic and non-staticdata members andmember functions, membertypedefs, memberenumerations, andnested classes. It may also be afriend declaration.
class S{int d1;// non-static data memberint a[10]={1,2};// non-static data member with initializer (C++11) staticconstint d2=1;// static data member with initializer virtualvoid f1(int)=0;// pure virtual member function std::string d3,*d4, f2(int);// two data members and a member function enum{ NORTH, SOUTH, EAST, WEST}; struct NestedS{std::string s;} d5,*d6; typedef NestedS value_type,*pointer_type;};
2) Function definitions, which both declare and define
member functions or
friend functions. A semicolon after a member function definition is optional. All functions that are defined inside a class body are automatically
inline, unless they are attached to anamed module(since C++20).
3)Access specifierspublic:
,
protected:
, and
private:
class S{public: S();// public constructor S(const S&);// public copy constructorvirtual ~S();// public virtual destructorprivate:int* ptr;// private data member};
4)Using-declarations:
class Base{protected:int d;}; class Derived:public Base{public:using Base::d;// make Base's protected member d a public member of Derivedusing Base::Base;// inherit all bases' constructors (C++11)};
[edit]Local classes
A class declaration can appear inside the body of a function, in which case it defines alocal class. The name of such a class only exists within the function scope, and is not accessible outside.
- Members of a local class can only be declared in the definition of that class, except that members that arenested classes can also be declared in the nearest enclosingblock scope of that class.
- A class nested within a local class is also a local class.
- A local class cannot have static data members.
- Member functions of a local class have no linkage.
- Member functions of a local class have to be defined entirely inside the class body.
- Local classes other thanclosure types(since C++14) cannot have member templates.
- Local classes cannot havefriend templates.
- Local classes cannot definefriend functions inside the class definition.
- A local class inside a function (including member function) can access the same names that the enclosing function can access.
- Local classes could not be used as template arguments.
| (until C++11) |
#include <algorithm>#include <iostream>#include <vector> int main(){std::vector<int> v{1,2,3}; struct Local{bool operator()(int n,int m){return n> m;}}; std::sort(v.begin(), v.end(), Local());// since C++11 for(int n: v)std::cout<< n<<' ';std::cout<<'\n';}
Output:
[edit]Keywords
class,struct,union
[edit]Defect reports
The following behavior-changing defect reports were applied retroactively to previously published C++ standards.
DR | Applied to | Behavior as published | Correct behavior |
---|
CWG 1693 | C++98 | member declarations could not be empty | empty declaration allowed |
CWG 1930 | C++98 | member-declarator-list could be empty whendecl-specifier-seq contains a storage class specifier or cv qualifier | the list must not be empty |
CWG 2890 | C++98 | it was unclear where the members of nested classes can be declared | made clear |
[edit]See also