首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

Non-static member functions

非静态成员函数是在成员规格类的静态或朋友说明符。

二次

代码语言:javascript
复制
class S {
    int mf1(); // non-static member function declaration
    void mf2() volatile, mf3() &&; // can be cv-qualified and reference-qualified
    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

二次

任何函数声明允许使用仅对非静态成员函数可用的附加语法元素:最终和覆盖说明符,纯规范,cv-限定符,ref-限定符,以及成员初始化列表...

可以调用X类的非静态成员函数。

1%29用于使用类成员访问运算符的X类型对象

2%29用于类的对象导出从X

3%29直接从X的成员函数体内

4%29直接从从X导出的类的成员函数体内

在任何其他类型的对象上调用X类的成员函数将调用未定义的行为。

在X的非静态成员函数的主体中,任何ID-表达式e%28 e.。将解析为X的非类型非静态成员或X基类的标识符%29转换为成员访问表达式。(*this).E%28,除非它已成为成员访问表达式%29的一部分。这在模板定义上下文中不会发生,因此名称可能必须以前缀。this->明示成相依...

二次

代码语言:javascript
复制
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
}

二次

在X的非静态成员函数的主体中,任何解析为静态成员的非限定id、枚举器或嵌套类型X或X的基类都被转换为相应的限定-id。

二次

代码语言:javascript
复制
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
}

二次

Const-、Volatile-和ref-限定成员函数

非静态成员函数可以使用Const、Volatile或Const挥发性限定符%28声明。此限定符出现在功能声明29%。不同的是,cv限定的函数有不同的类型,因此可能会使彼此超载。

在cv限定函数的主体中,这指针是cv限定的,例如在const成员函数,通常只能调用其他Const成员函数。%28a非连续成员函数仍可被调用,如果康斯特[医]铸造应用,或通过不涉及以下内容的访问路径应用这.%29

二次

代码语言:javascript
复制
#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
}

二次

A non-static member function can be declared with no ref-qualifier, with an lvalue ref-qualifier (the token & after the function name) or the rvalue ref-qualifier (the token && after the function name). During overload resolution, non-static cv-qualified member function 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 the this pointer: within a rvalue ref-qualified function, *this remains an lvalue expression.

(since C++11)

  • 没有ref-限定符:隐式对象参数具有对cv限定X的类型lvalue引用,并且还允许绑定rvalue隐含对象参数。
  • lvalue ref-限定符:隐式对象参数具有对cv限定X的lvalue引用类型。
  • rvalue ref-限定符:隐式对象参数具有对cv限定X的类型rvalue引用。

#包括<iostream>结构S{voidf%28%29&{std::cout<<“lvalue\n”;}voidf%28%29&{std:cout<<“rvalue\n”};int main%28%29{s;S.F%28%29;//打印“lvalue”std::Move%28s%29。F%28%29;//打印“rvalue”S%28%29。F%28%29;//打印“rvalue”}

注意:与cv-资质不同,ref-资质不会更改这指针:在rvalue ref限定函数中,*this仍然是一个lvalue表达式。

%28自C++11%29

虚纯虚函数

可以声明非静态成员函数。虚拟纯虚拟.见虚函数和抽象类关于细节。

特殊成员函数

建设者和破坏者是对声明%28使用特殊语法的非公共成员函数,有关详细信息,请参阅其页%29。

一些成员函数是特制在某些情况下,它们是由编译器定义的,即使用户没有定义它们。它们是:

  • 默认构造函数
  • 复制构造函数
  • 移动构造函数%28自C++11%29
  • 复制赋值算子
  • 移动赋值算子%28自C++11%29
  • 破坏者

特殊成员函数是唯一可以违约,也就是说,使用= default有关详细信息,请参阅其页面,而不是函数体%28。

二次

代码语言:javascript
复制
#include <iostream>
#include <string>
#include <utility>
#include <exception>
 
struct S {
    int data;
 
    // simple converting constructor (declaration)
    S(int val);
 
    // simple explicit constructor (declaration)
    explicit S(std::string str);
 
    // const member function (definition)
    virtual int getData() const { return data; }
 
};
 
// definition of the constructor
S::S(int val) : data(val) {
    std::cout << "ctor1 called, data = " << data << '\n';
}
 
// this constructor has a catch clause
S::S(std::string str) try : data(std::stoi(str)) {
    std::cout << "ctor2 called, data = " << data << '\n';
} catch(const std::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 function
    int 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(const std::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=
}

二次

产出:

二次

代码语言:javascript
复制
ctor1 called, data = 1
ctor2 called, data = 2
ctor2 failed, string was 'not a number'
2
ctor1 called, data = 3

二次

另见

  • 数据成员
  • 静态数据成员
代码语言:txt
复制
 © cppreference.com

在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。

扫码关注腾讯云开发者

领取腾讯云代金券