特殊名字的函数
或者含有一个类类型参数
或者是类的成员(就会含有隐式this指针)
[ "::", ".*", ".", " ? : " ]
逗号/取地址/逻辑与/逻辑或
-
赋值/下标/调用/成员访问 必成员
-
复合赋值 大概率成员
-
改变状态/密切相关 大概率成员
-
有对称性的运算符 通常非成员
对称性举例:char* 与 string ,加号运算符 若+定义为成员,则默认string为第一位。
- 建议算数运算符用复合赋值运算符实现 (+ 调用 +=)
- 建议不等判断调用相等判断 (!= 调用 ==)
- 建议下标运算符定义const引用和非const引用两个版本
- 后置自增/自减可以用前置来实现
不那么直观。
对于内置指针和自定义类型有不同的解释方式
ptr->func();
//to
(*ptr).func();
myClass->func();
//to
(myClass.operator->())->func();
综上,自定义类的成员访问运算符最后应返回一个内置指针
当然你也可以返回一个定义了成员访问运算符的对象
然后递归的执行这个操作
名称 | 表示 | 定义 |
---|---|---|
前置自增 | ++myClass; | MyClass& operator++(); |
后置自增 | myClass++; | MyClass& operator++(int = 0); //一般不用这个0,由编译器提供 |
前置自减 | --myClass; | MyClass& operator--(); |
后置自减 | myClass--; | MyClass& operator--(int = 0); |
看起来是匿名函数
实质编译器帮你做的是产生一个匿名类的匿名对象
这个匿名类的构造器对应了捕获列表[...]
重载operator()对应了参数列表(...)和函数体{...}
名称 | 含义 |
---|---|
plus<> | 加 |
minus<> | 减 |
multiplies<> | 乘 |
divides<> | 除 |
modulus<> | 模 |
negate<> | 负 |
equal_to<> | 等 |
not_equal_to<> | 不等 |
greater<> | 大于 |
greater_equal<> | 大于等于 |
less<> | 小于 |
less_equal<> | 小于等于 |
logical_and<> | 与 |
logical_or<> | 或 |
logical_not<> | 非 |
可调用对象:函数/函数指针/lambda/bind创建的/仿函数
他们可以有相同的**调用形式**
如 int(double, int)
我们创建函数表时,可以写作如下形式
map<string,int(*)(double, int)>
也可以写作如下
map<string,fucnction<int(double, int)>>
- 本类转为其他类时用到的运算符
- 通常为const
- 不用(也不能)显式指定返回类型
- 必须作为成员函数
- 不能有参数
- 需要时加explicit来避免隐式调用
(注意:用作条件时explicit无效)
(注意:用作条件时explicit无效)
(注意:用作条件时explicit无效)
class MyClass{
int val;
operator int() const {
return val;
};
};
//def:
class A{
A(B);
};
class B{
operator A() const {...};
};
void func(A);
//call:
func(B());
解决方法:
- 去的路和回来的路最好只给一条
- 类似的路(int/double)最好只给一条
- 如果只能都给,那调用的时候请显示调用
偏移型指针,记录了类中某成员的地址偏移。
使用的时候需要提供一个对象。
//我真没见过有人用这沙雕东西
class MyClass{
public:
int val;
void setVal(int v){
val = v;
};
};
MyClass myClass;
shared_ptr<MyClass> sptrM = make_shared<MyClass>();
auto ep = &MyClass::val;
//int MyClass::*ep = &MyClass::val;
auto fp = &MyClass::setVal;
//void (MyClass::*fp)(int) = &MyClass::setVal;
myClass.*ep = 666;
(myClass.*fp)(777);
sptrM.get()->*ep = 666;
(sptrM.get()->*fp)(777);