Non-static member functions
非静态成员函数
非静态成员函数是在成员规格类的静态或朋友说明符。
二次
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->明示成相依...
二次
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。
二次
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
二次
#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 | (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。
例
二次
#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=
}
二次
产出:
二次
ctor1 called, data = 1
ctor2 called, data = 2
ctor2 failed, string was 'not a number'
2
ctor1 called, data = 3
二次
另见
- 班
- 数据成员
- 静态数据成员
© cppreference.com
在CreativeCommonsAttribution下授权-ShareAlike未移植许可v3.0。