Namespaces
Variants
Views
Actions

Non-static member functions

From cppreference.com
< cpp‎ | language
Revision as of 22:36, 7 June 2013 by Cubbi (Talk | contribs)

 
 
C++ language
General topics
Flow control
Conditional execution statements
Iteration statements
Jump statements
Functions
function declaration
lambda function declaration
function template
inline specifier
exception specifications (deprecated)
noexcept specifier (C++11)
Exceptions
Namespaces
Types
decltype specifier (C++11)
Specifiers
cv specifiers
storage duration specifiers
constexpr specifier (C++11)
auto specifier (C++11)
alignas specifier (C++11)
Initialization
Literals
Expressions
alternative representations
Utilities
Types
typedef declaration
type alias declaration (C++11)
attributes (C++11)
Casts
implicit conversions
const_cast conversion
static_cast conversion
dynamic_cast conversion
reinterpret_cast conversion
C-style and functional cast
Memory allocation
Classes
Class-specific function properties
Special member functions
Templates
class template
function template
template specialization
parameter packs (C++11)
Miscellaneous
Inline assembly
 

Non-static member functions are the functions that are declared in a member specification of a class without a static or friend specifier.

class S {
    int mf1(); // non-static member function declaration
    void mf2() volatile, mf3() &&; // can be cv-qualified and reference-qualifie
    int mf4() const { return data; } // can be defined inline
    virtual void mf5() final; // can be virtual, can use final/override
    S() : data(12) {} // constructors are member functions too
    int data;
};
int S::mf1() { return 7; } // if not defined inline, has to be defined at namespace

Any function declarations are allowed, with additional syntax elements that are only available for non-static member functions: virtual specifiers, final and override specifiers, cv-qualifiers, ref-qualifiers, and member initialization lists.

A non-static member function of class X may be called

1) For an object of type X using the class member access operator
2) For an object of a class derived from X
3) Directly from within the body of a member function of X
4) Directly from within the body of a member function of a class derived from X

Calling a member function of class X on an object of any other type invokes undefined behavior.

Within the body of a non-static member function of X, any id-expression E (e.g. an identifier) that resolves to a non-type non-static member of X or of a base class of X, is transformed to a member access expression (*this).E (unless it's already a part of a member access expression)

struct S {
    int n;
    void f();
};
void S::f() {
    n = 1; // transformed to (*this).n = 1;
}
int main() {
    S s1, s2;
    s1.f(); // changes s1.n
}

Within the body of a non-static member function of X, any unqualified-id that resolves to a static member, an enumerator or a nested type of X or of a base class of X, is transformed to the corresponding qualified-id.

struct S {
    static int n;
    void f();
};
void S::f() {
    n = 1; // transformed to S::n = 1;
}
int main() {
    S s1, s2;
    s1.f(); // changes S::n
}

Contents

const-, volatile-, and ref-qualified member functions

A non-static member function can be declared with a const, volatile, or const volatile qualifier (this qualifier appears after the name of the function in function declaration). Differently cv-qualified functions have different types and so may overload each other.

In the body of a cv-qualified function, the this pointer is cv-qualified, e.g. in a const member function, only other const member functions may be called.

#include <vector>
struct Array {
    std::vector<int> data;
    Array(int sz) : data(sz) {}
    // const member function
    int operator[](int idx) const {
                          // this has type const Array*
        return data[idx]; // transformed to (*this).data[idx];
    }
    // non-const member function
    int& operator[](int idx) {
                          // this has type Array*
        return data[idx]; // transformed to (*this).data[idx]
    }
};
int main()
{
    Array a(10);
    a[1] = 1; // OK: the type of a[1] is int&
    const Array ca(10);
    ca[1] = 2; // Error: the type of ca[1] is int
}

(since C++11) A non-static member function can be declared with either an lvalue ref-qualifier (the character & after the function name) or rvalue ref-qualifier (the character && after the function name. During overload resolution, non-static cv-qualified member function of class X is treated as a function that takes an implicit parameter of type lvalue reference to cv-qualified X if it has no ref-qualifiers or if it has the lvalue ref-qualifier. Otherwise (if it has rvalue ref-qualifier), it is treated as a function taking an implicit parameter of type rvalue reference to cv-qualified X.

#include <iostream>
struct S {
    void f() & { std::cout << "lvalue\n"; }
    void f() &&{ std::cout << "rvalue\n"; }
};
 
int main(){
    S s;
    s.f();            // prints "lvalue"
    std::move(s).f(); // prints "rvalue"
    S().f();          // prints "rvalue"
}

Note: unlike cv-qualification, ref-qualification does not change the properties of the this pointer: within a rvalue ref-qualified function, *this remains an lvalue expression.

Virtual and pure virtual functions

A non-static member function may be declared virtual or pure virtual. See virtual functions and abstract classes for details.

Special member functions

See also