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. The keywords are identical except for the default member access and the default base class access. |
attr(C++11) | - | optional sequence of any number of attributes, may include alignas specifier |
class-head-name | - | the name of the class that's being defined. Optionally qualified, 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.
A declaration of the following form.
class-key attr identifier ; |
Declares a class type 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 }
Note that a new class name may also be introduced by an elaborated type specifier which appears as part of another declaration, but only if name 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 Y* p; T* q; // can use pointers and references to T and Y }
The member specification, or the body of a class definition, is a brace-enclosed sequence of any number of the following:
attr(optional) decl-specifier-seq(optional) member-declarator-list(optional) ; |
attr(C++11) | - | optional sequence of any number of attributes |
decl-specifier-seq | - | sequence of specifiers. It is only optional in the declarations of constructors, destructors, and user-defined type conversion functions |
member-declarator-list | - | similar to a init-declarator-list, but additionally allows bit-field declaration, pure-specifier, and virt-specifier (override or final ) (since C++11), and does not allow direct-non-list-initialization syntax. |
This declaration may declare static and non-static data members and member functions, member typedefs, member enumerations, and nested classes. It may also be a friend declaration.
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; }; };
8) deduction guides of member class templates: struct S { template<class CharT> struct NestedS { std::basic_string<CharT> s; }; template<class CharT> NestedS(std::basic_string<CharT>) -> NestedS<CharT>; }; | (since C++17) |
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 class), and inside the body of a function, in which case it defines a local class. The name of such a class only exists within the function scope, and is not accessible outside.
| (until C++11) |
#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
C documentation for Struct declaration |
© cppreference.com
Licensed under the Creative Commons Attribution-ShareAlike Unported License v3.0.
http://en.cppreference.com/w/cpp/language/class