Class declaration

< cpp‎ | language
Revision as of 07:39, 30 June 2013 by Cubbi (Talk | contribs)

C++ language
General topics
Flow control
Conditional execution statements
Iteration statements (loops)
Jump statements
Function declaration
Lambda function declaration
inline specifier
Exception specifications (deprecated)
noexcept specifier (C++11)
Compound types
Union types
decltype (C++11)
auto (C++11)
alignas (C++11)
Storage duration specifiers
Alternative representations
Boolean - Integer - Floating-point
Character - String - nullptr (C++11)
User-defined (C++11)
Attributes (C++11)
typedef declaration
Type alias declaration (C++11)
Implicit conversions - Explicit conversions
static_cast - dynamic_cast
const_cast - reinterpret_cast
Memory allocation
Class-specific function properties
Special member functions

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.

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

Member specification

The member specification, or the body of a class definition, is a brace-enclosed sequence of any number of the following:

1) Member declarations, which are declarations of static and non-static data members and member functions, typedef declarations, scoped and unscoped enumerations, and other, nested, class declarations.
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;
2) Function definitions, which both declare and define member functions. A semicolon after a member function definition is optional. All member functions that are defined inside a class body are automaticaly inline.
class M {
    std::size_t C;
    std::vector<int> data;
    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];
3) Access specifiers public:, protected:, and private:
class S {
    S();          // public constructor
    S(const S&);  // public copy constructor
    virtual ~S(); // public virtual destructor
    int* ptr; // private data member
4) Using-declarations
class Base {
     int d;
class Derived : public Base {
    using Base::d; // make Base's protected member d a public member of Derived
    using Base::Base; // inherit all parent's constructors (C++11)
5) static_assert declarations
template<typename T>
struct Foo {
  static_assert(std::is_floating_point<T>::value, "Foo<T>: T must be floating point");
6) member template declarations
struct S {
    template<typename T>
    void f(T&& n);
    template<class CharT>
    struct NestedS {
        std::basic_string<CharT> s;
7) alias declarations
template <typename T>
struct identity
    using type = T;

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.
  • local classes could not be used as template arguments
(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 << ' ';


3 2 1