C++ 函数

函数

函数指针

  • 使用函数指针把函数当做参数传递

  • ```c++
    //定义一个函数
    void print(string& content) {

    cout << content << endl;
    

    }

    //函数的第一个参数就是函数指针
    void callPrint(void (*f) (string&), string& param) {

    f(param); //调用函数指针指向的函数
    

    }

    int main() {

    string content{ "allen" };
    //使用函数指针,把print方法当做参数直接传递给callPrint方法
    callPrint(print, content); //输出allen
    return 0;
    

    }

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16

    - 代码 `void (*f) (string&)` 定义了一个函数指针

    - f 是函数指针变量名

    - 这个指针指向一个接收 string 引用且无返回值的方法

    - 可以使用 `auto f` 替代上面那一坨

    - 可以使用 `using` 定义别名

    - ```c++
    using printType = void (*) (string&);
    void callPrint(printType f, string& param) {
    f(param);
    }

函数对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
//函数对象类型
class MyFunction {
public:
//重载函数调用运算符
int operator()(int x, int y) {
return x + y;
}
//函数调用运算符的重载版本
double operator()(double x, double y) {
return x * y;
}
};

int main() {
MyFunction func; //函数对象
cout << func(12, 13) << " " << func(3.2,19.8) << endl; /才使用函数对象
//执行函数对象上的方法,输出:25 63.36
return 0;
}
  • 函数对象就是一个重载了函数调用运算符 operator()() 的普通的对象

std::function 模板

1
2
3
4
5
6
#include <functional> //std::function定义在这个头文件中

//f是一个function类型的对象。
void callFunction(function<int(int, int)> f,int param1,int param2) {
cout << f(param1,param2) << endl;
}
  • 使用 std::function 定义的参数可以同时接受函数指针函数对象

匿名函数(lambda 表达式)

  • 定义形式[capture](parameters) -> returnType { body }
  • [capture]用于让匿名函数的内部逻辑具备访问匿名函数外部变量的能力
  • (parameters) 用于声明匿名函数的参数
  • -> returnType 是匿名函数返回值类型(返回类型后置,一般可以忽略)
  • { body }是匿名函数的函数体

lambda 捕获外部变量

  • [],不捕获任何外部变量,此时在匿名函数体内使用外部变量都会报错。
  • [=]:按值捕获所有外部变量。
  • [&]:按引用捕获所有外部变量。
  • [x, &y]:x 按值捕获,y 按引用捕获。
  • [&, x]:x 按值捕获,其他变量按引用捕获。
  • [=, &x]:x 按引用捕获,其他变量按值捕获。
  • [this]:捕获匿名函数所在作用域的对象,this 是当前对象的指针,此时不会复制整个对象。
  • [*this]:捕获匿名函数所在作用域的对象的副本,此时会复制整个对象。

使用 [=][&] 捕捉外部变量时,只有在匿名函数体内真正使用到的变量才会被复制或引用

1
2
3
4
5
6
7
8
9
10
11
12
int main() {
string str { "等忙完这一阵子," };
string str2 {"就可以接着忙下一阵子了。"};
// 按引用捕获变量 str
auto print = [&str](string& param) {
string str2 { "马克思说:" };
// 输出: 马克思说:等忙完这一阵子,就可以接着忙下一阵子了。
cout << str2 << str << param << std::endl;
};
print(str2);
return 0;
}

泛型匿名函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// 注意此方法的返回值是auto类型的,实际上返回的是一个方法指针
auto getFunction() {
// 注意:这里匿名函数的参数类型被定义为auto
// 其实是一个模板函数,允许开发者向它传递不同类型的参数
auto print = [](auto param) {
std::cout << param << std::endl;
};
return print;
}

int main() {
// 得到匿名函数的方法指针
auto print = getFunction();
print(123); //输出:123
print("liulun"); //输出:liulun
return 0;
}

this 指针与链式调用

**在执行一个对象的成员函数时,编译器会为该成员函数自动生成一个指针:this**,这个指针就是调用该成员函数的对象指针。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class ORM {
public:
ORM* Select(const char* param) {
cout << param << endl;
return this; //返回当前对象指针
}
ORM* From(const char* param) {
cout << param << endl;
return this;
}
ORM* Where(const char* param) {
cout << param << endl;
return this;
}
ORM* OrderBy(const char* param) {
cout << param << endl;
return this;
}
};

int main() {
ORM* orm {new ORM()};
orm->Select("userName")->From("user")->Where("id=123")->OrderBy("createTime");
return 0;
}
  • 执行对象的成员函数时,我们可以在函数体内直接访问对象的成员变量或方法

    • 编译器把这样的代码:callYourClassMethod();,翻译成这样的代码:this->callYourClassMethod();
作者

大下坡

发布于

2023-11-13

更新于

2023-11-13

许可协议