Movatterモバイル変換


[0]ホーム

URL:


cppreference.com
Namespaces
Variants
    Actions

      Non-static member functions

      From cppreference.com
      <cpp‎ |language
       
       
      C++ language
      General topics
      Flow control
      Conditional execution statements
      Iteration statements (loops)
      Jump statements
      Functions
      Function declaration
      Lambda function expression
      inline specifier
      Dynamic exception specifications(until C++17*)
      noexcept specifier(C++11)
      Exceptions
      Namespaces
      Types
      Specifiers
      constexpr(C++11)
      consteval(C++20)
      constinit(C++20)
      Storage duration specifiers
      Initialization
      Expressions
      Alternative representations
      Literals
      Boolean -Integer -Floating-point
      Character -String -nullptr(C++11)
      User-defined(C++11)
      Utilities
      Attributes(C++11)
      Types
      typedef declaration
      Type alias declaration(C++11)
      Casts
      Memory allocation
      Classes
      Class-specific function properties
      Special member functions
      Templates
      Miscellaneous
       
       

      A non-static member function is a function that is declared in amember specification of a class without astatic orfriend specifier(seestatic member functions andfriend declaration for the effect of those keywords).

      class S{int mf1();// non-static member function declarationvoid mf2()volatile, mf3()&&;// can have cv-qualifiers and/or a reference-qualifier// the declaration above is equivalent to two separate declarations:// void mf2() volatile;// void mf3() &&; int mf4()const{return data;}// can be defined inlinevirtualvoid mf5() final;// can be virtual, can use final/override    S(): data(12){}// constructors are member functions tooint data;}; int S::mf1(){return7;}// if not defined inline, has to be defined at namespace

      Constructors,destructors, andconversion functions use special syntaxes for their declarations. The rules described in this page may not apply to these functions. See their respective pages for details.

      Anexplicit object member function is a non-static member function with anexplicit object parameter.

      (since C++23)

      Animplicit object member function is a non-static member function without an explicit object parameter (prior to C++23, this was the only kind of non-static member function, and hence referred to as "non-static member function" in the literature).

      Contents

      [edit]Explanation

      Anyfunction declarations are allowed, with additional syntax elements that are only available for non-static member functions:pure-specifiers, cv-qualifiers, ref-qualifiers,final andoverride specifiers(since C++11), andmember initialization lists.

      A non-static member function of classX may be called

      1) For an object of typeX using the class member access operator
      2) For an object of a classderived fromX
      3) Directly from within the body of a member function ofX
      4) Directly from within the body of a member function of a class derived fromX

      Calling a non-static member function of classX on an object that is not of typeX, or of a type derived fromX invokes undefined behavior.

      Within the body of a non-static member function ofX, anyid-expressione (e.g. an identifier) that resolves to a non-type non-static member ofX or of a base class ofX, is transformed to a member access expression(*this).e (unless it's already a part of a member access expression). This does not occur in template definition context, so a name may have to be prefixed withthis-> explicitly to becomedependent.

      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 ofX, any unqualified-id that resolves to a static member, an enumerator or a nested type ofX or of a base class ofX, is transformed to the corresponding qualified-id:

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

      [edit]Member functions with cv-qualifiers

      An implicit object member function can be declared with acv-qualifier sequence (const,volatile, or a combination ofconst andvolatile), this sequence appears after the parameter list in thefunction declaration. Functions with different cv-qualifier sequences (or no sequence) have different types and so may overload each other.

      In the body of a function with a cv-qualifier sequence,*this is cv-qualified, e.g. in a member function withconst qualifier, only other member functions withconst qualifier may be called normally. A member function withoutconst qualifier may still be called ifconst_cast is applied or through an access path that does not involvethis.

      #include <vector> struct Array{std::vector<int> data;    Array(int sz): data(sz){} // const member functionint operator[](int idx)const{// the this pointer has type const Array*return data[idx];// transformed to (*this).data[idx];} // non-const member functionint& operator[](int idx){// the this pointer 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}

      Member functions with ref-qualifier

      An implicit object member function can be declared with no ref-qualifier, with an lvalue ref-qualifier (the token& after the parameter list) or the rvalue ref-qualifier (the token&& after the parameter list). Duringoverload resolution, an implicit object member function with a cv-qualifier sequence of class X is treated as follows:

      • no ref-qualifier: the implicit object parameter has type lvalue reference to cv-qualified X and is additionally allowed to bind rvalue implied object argument
      • lvalue ref-qualifier: the implicit object parameter has type lvalue reference to cv-qualified X
      • rvalue ref-qualifier: the implicit object parameter has 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 thethis pointer: within an rvalue ref-qualified function,*this remains an lvalue expression.

      (since C++11)

      [edit]Virtual and pure virtual functions

      A non-static member function may be declaredvirtual orpure virtual. Seevirtual functions andabstract classes for details.

      Explicit object member functions

      For a non-static non-virtual member function not declared with cv-qualifier or ref-qualifier, its first parameter, if not being afunction parameter pack, can be anexplicit object parameter (denoted with the prefixed keywordthis):

      struct X{void foo(this Xconst& self,int i);// same as void foo(int i) const &;//  void foo(int i) const &; // Error: already declared void bar(this X self,int i);// pass object by value: makes a copy of “*this”};

      For member function templates, explicit object parameter allows deduction of type and value category, this language feature is called “deducingthis”:

      struct X{template<typename Self>void foo(this Self&&,int);}; struct D: X{}; void ex(X& x, D& d){    x.foo(1);// Self = X&    move(x).foo(2);// Self = X    d.foo(3);// Self = D&}

      This makes it possible to deduplicate const- and non-const member functions, seearray subscript operator for an example.

      Inside the body of an explicit object member function, thethis pointer cannot be used: all member access must be done through the first parameter, like in static member functions:

      struct C{void bar(); void foo(this C c){auto x= this;// error: no this        bar();// error: no implicit this->        c.bar();// ok}};

      A pointer to an explicit object member function is an ordinary pointer to function, not a pointer to member:

      struct Y{int f(int,int)const&;int g(this Yconst&,int,int);}; auto pf=&Y::f;pf(y,1,2);// error: pointers to member functions are not callable(y.*pf)(1,2);// okstd::invoke(pf, y,1,2);// ok auto pg=&Y::g;pg(y,3,4);// ok(y.*pg)(3,4);// error: “pg” is not a pointer to member functionstd::invoke(pg, y,3,4);// ok
      (since C++23)

      [edit]Special member functions

      Some member functions arespecial: under certain circumstances they are defined by the compiler even if not defined by the user. They are:

      (since C++11)
      (since C++11)

      Special member functionsalong with thecomparison operators(since C++20) are the only functions that can bedefaulted, that is, defined using=default instead of the function body (see their pages for details).

      [edit]Notes

      Feature-test macroValueStdFeature
      __cpp_ref_qualifiers200710L(C++11)ref-qualifiers
      __cpp_explicit_this_parameter202110L(C++23)explicit object parameter (deducingthis)

      [edit]Example

      Run this code
      #include <exception>#include <iostream>#include <string>#include <utility> struct S{int data; // simple converting constructor (declaration)    S(int val); // simple explicit constructor (declaration)explicit S(std::string str); // const member function (definition)virtualint getData()const{return data;}}; // definition of the constructorS::S(int val): data(val){std::cout<<"ctor1 called, data = "<< data<<'\n';} // this constructor has a catch clauseS::S(std::string str)try: data(std::stoi(str)){std::cout<<"ctor2 called, data = "<< data<<'\n';}catch(conststd::exception&){std::cout<<"ctor2 failed, string was '"<< str<<"'\n";throw;// ctor's catch clause should always rethrow} struct D: S{int data2;// constructor with a default argument    D(int v1,int v2=11): S(v1), data2(v2){} // virtual member functionint getData()const override{return data* data2;} // lvalue-only assignment operator    D& operator=(D other)&{std::swap(other.data, data);std::swap(other.data2, data2);return*this;}}; int main(){    D d1=1;    S s2("2"); try{        S s3("not a number");}catch(conststd::exception&){} std::cout<< s2.getData()<<'\n';     D d2(3,4);    d2= d1;// OK: assignment to lvalue//  D(5) = d1; // ERROR: no suitable overload of operator=}

      Output:

      ctor1 called, data = 1ctor2 called, data = 2ctor2 failed, string was 'not a number'2ctor1 called, data = 3

      [edit]Defect reports

      The following behavior-changing defect reports were applied retroactively to previously published C++ standards.

      DRApplied toBehavior as publishedCorrect behavior
      CWG 194C++98ambiguous whether a non-static member function
      could have the same name as the enclosing class name
      explicit naming restriction added

      [edit]See also

      Retrieved from "https://en.cppreference.com/mwiki/index.php?title=cpp/language/member_functions&oldid=180344"

      [8]ページ先頭

      ©2009-2025 Movatter.jp