Class declaration
Classes and structs are user-defined types, defined by class-specifier, which appears in decl-specifier-seq of the declaration syntax. The class specifier has the following syntax:
class-key attr class-head-name base-clause { member-specification }
|
|||||||||
class-key | - | one of class or struct |
attr(C++11) | - | optional sequence of any number of attributes |
class-head-name | - | the name of the class that's being defined. Optionally prepended by nested-name-specifier (sequence of names and scope-resolution operators, ending with scope-resolution operator), optionally followed by keyword final. The name may be omitted, in which case the class is unnamed (note that unnamed class cannot be final) |
base-clause | - | optional list of one or more parent classes and the model of inheritance used for each (see derived class) |
member-specification | - | list of access specifiers, member object and member function declarations and definitions (see below) |
See classes for general overview of the syntax. If class-key is union
, the declaration introduces a union type.
[edit] Forward declaration
A declaration of the following form
class-key attr identifier ;
|
|||||||||
Declares a class or struct which will be defined later in this scope. Until the definition appears, this class name has incomplete 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; friend std::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, it hides 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 }
[edit] Member specification
The member specification, or the body of a class definition, is a brace-enclosed sequence of any number of the following:
class S { int d1; // non-static data member int a[10] = {1,2}; // non-static data member with initializer (C++11) static const int d2 = 1; // static data member with initializer virtual void 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; };
class M { std::size_t C; std::vector<int> data; public: M(std::size_t R, std::size_t C) : C(C), data(R*C) {} // constructor definition int operator()(size_t r, size_t c) const { // member function definition return data[r*C+c]; } int& operator()(size_t r, size_t c) { // another member function definition return data[r*C+c]; } };
public:
, protected:
, and private:
class S { public: S(); // public constructor S(const S&); // public copy constructor virtual ~S(); // public virtual destructor private: int* ptr; // private data member };
class Base { protected: int d; }; class Derived : public Base { public: using Base::d; // make Base's protected member d a public member of Derived using Base::Base; // inherit all parent's constructors (C++11) };
template<typename T> struct Foo { static_assert(std::is_floating_point<T>::value, "Foo<T>: T must be floating point"); };
struct S { template<typename T> void f(T&& n); template<class CharT> struct NestedS { std::basic_string<CharT> s; }; };
[edit] Local classes
A class declaration can appear in namespace scope (in which case it defines an ordinary class), inside another class definition (in which case it defines a nested type, and inside the body of a function, in which case it defines a local class. This class only exists within the function scope, and is not accessible outside.
- A local class cannot have static 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 cannot have member templates or friend templates
- A local class inside a function (including member function) can access the same names that the enclosing function can access.
- (until C++11) local classes could not be used as template arguments
#include <vector> #include <algorithm> #include <iostream> 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 << ' '; }
Output:
3 2 1