济南做网站最好的公司,企业宣传片策划方案,企业网络安全设计方案,银川网页设计公司目录
前言
一、按“是否属于类”划分#xff1a;成员 / 非成员
1.1 成员函数#xff08;Member Function#xff09;
1#xff09;定义
2#xff09;分类
#xff08;1#xff09;非静态成员函数
#xff08;2#xff09;静态成员函数#xff08;Static Membe…目录前言一、按“是否属于类”划分成员 / 非成员1.1 成员函数Member Function1定义2分类1非静态成员函数2静态成员函数Static Member Function1.2 非成员函数Free Function1定义2示例1全局函数2命名空间内函数3文件内静态函数内部链接1.3 友元函数Friend Function1定义2示例常见于 operator二、按“是不是特殊成员函数”划分存在C 标准2.1 构造函数Constructor1默认构造函数2带参数构造函数3委托构造函数2.2 拷贝构造函数Copy Constructor2.3 移动构造函数Move Constructor2.4 拷贝赋值运算符Copy Assignment2.5 移动赋值运算符Move Assignment2.6 析构函数Destructor三、按“多态特性”划分普通 / 虚函数 / 纯虚函数3.1 普通成员函数3.2 虚函数virtual3.3 纯虚函数pure virtual四、按“修饰符”划分const / ref 限定 / noexcept / inline4.1 const 成员函数4.2 引用限定符成员函数 / 4.3 noexcept 函数4.4 inline 函数五、按“编译期特性”划分模板 / constexpr / consteval5.1 函数模板Function Template5.2 constexpr 函数可用于常量表达式5.3 consteval 函数必须在编译期算六、可调用对象扩展lambda / 函数对象 / 函数指针6.1 Lambda 表达式6.2 函数对象仿函数6.3 函数指针 成员函数指针七、总表C 函数“类型家族”一览八、总结在之前的学习中已经详细的介绍了成员函数、构造 / 析构函数、成员函数运算符重载、多态虚函数、C变量作用域的相关内容。想要迅速了解传送门C 内存机制详细全讲解构造函数、析构函数、new/delete、栈 vs 堆 完整指南小白教程_结构体构造函数是堆内存还是栈内存-CSDN博客https://blog.csdn.net/m0_58954356/article/details/155098091?spm1001.2014.3001.550221. 图形的面积 —— C多态与虚函数实战讲解_经典的c21 版项目-CSDN博客https://blog.csdn.net/m0_58954356/article/details/154449284?ops_request_misc%257B%2522request%255Fid%2522%253A%25228da7df0f814a6cb6c720203ffe8d202c%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257Drequest_id8da7df0f814a6cb6c720203ffe8d202cbiz_id0utm_mediumdistribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-8-154449284-null-null.nonecaseutm_term%E5%87%BD%E6%95%B0spm1018.2226.3001.4450C 变量作用域详解最全总结_c作用域-CSDN博客https://blog.csdn.net/m0_58954356/article/details/154583518?ops_request_misc%257B%2522request%255Fid%2522%253A%25228da7df0f814a6cb6c720203ffe8d202c%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257Drequest_id8da7df0f814a6cb6c720203ffe8d202cbiz_id0utm_mediumdistribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-18-154583518-null-null.nonecaseutm_term%E5%87%BD%E6%95%B0spm1018.2226.3001.4450C 多态终极完整版从虚函数到 vtable、对象切片、插件框架设计、面试题库全覆盖-CSDN博客https://blog.csdn.net/m0_58954356/article/details/154891712?ops_request_misc%257B%2522request%255Fid%2522%253A%25228da7df0f814a6cb6c720203ffe8d202c%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257Drequest_id8da7df0f814a6cb6c720203ffe8d202cbiz_id0utm_mediumdistribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-4-154891712-null-null.nonecaseutm_term%E5%87%BD%E6%95%B0spm1018.2226.3001.4450C 成员函数运算符重载深度解析-CSDN博客https://blog.csdn.net/m0_58954356/article/details/155754511?ops_request_misc%257B%2522request%255Fid%2522%253A%25228da7df0f814a6cb6c720203ffe8d202c%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257Drequest_id8da7df0f814a6cb6c720203ffe8d202cbiz_id0utm_mediumdistribute.pc_search_result.none-task-blog-2~blog~first_rank_ecpm_v1~rank_v31_ecpm-1-155754511-null-null.nonecaseutm_term%E5%87%BD%E6%95%B0spm1018.2226.3001.4450前言C 中“函数”远不止void foo()这么简单。从最基础的成员函数与非成员函数到类内部的构造 / 析构 / 拷贝 / 移动到支持多态的virtual / override / pure virtual再到编译期机制的模板函数 / constexpr / consteval以及现代 C 常用的lambda、函数对象、函数指针、成员函数指针……这些构成了 C 中“可调用实体Callable Entities”的完整体系。很多人在学习 C 时只了解成员函数非成员函数 / 全局函数静态成员函数但实际上这只是函数分类的“冰山一角”。在面试和实际工程中面试官常常会问C 函数到底分为哪些类型成员函数与非成员函数的本质区别是什么构造、析构、拷贝构造属于哪类函数虚函数、纯虚函数的机制是什么const 成员函数与 static 成员函数的区别lambda 与函数对象是否属于函数constexpr / consteval 函数有什么用为了帮助大家彻底厘清 C 函数体系结构这篇文章将从多个角度类归属、多态属性、特殊规则、编译期、可调用对象系统梳理 C 中所有常见的函数类型并配合示例代码、适用场景、对比表格一站式掌握面试高频点。一、按“是否属于类”划分成员 / 非成员1.1 成员函数Member Function1定义定义在类内部属于类。调用时有一个隐藏参数this指向调用对象。可以直接访问该类所有成员包括 private / protected。2分类非静态成员函数普通的成员函数静态成员函数static修饰不依赖对象1非静态成员函数class Vec2 { public: double x, y; void set(double nx, double ny) { // 非静态成员函数 x nx; // 实际是 this-x nx; y ny; } double length() const { // const 成员函数 return std::sqrt(x * x y * y); } };调用Vec2 v; v.set(1, 2); double len v.length();2静态成员函数Static Member Function只能访问静态成员class Config { public: static int version; static int getVersion() { // 静态成员函数 return version; // 只能访问静态成员 } }; int Config::version 1; int main() { int v Config::getVersion(); // 不需要对象 }特点无this指针。不能访问非静态成员。用于“类级别”的逻辑计数器、工厂、单例等。1.2 非成员函数Free Function1定义定义在类外部不属于任何类。没有this指针。不能直接访问类的 private 成员除非做友元。又可以细分全局函数在全局作用域命名空间内函数静态自由函数static内部链接2示例1全局函数int add(int a, int b) { return a b; } int main() { int r add(1, 2); }2命名空间内函数namespace math { int sub(int a, int b) { return a - b; } }3文件内静态函数内部链接static void logInternal(const std::string msg) { // 只能在当前 .cpp 文件内可见 }1.3 友元函数Friend Function1定义语法上是非成员函数但被类声明为friend。可以访问该类的private / protected成员。2示例常见于operatorclass Vec2 { private: double x, y; public: Vec2(double x, double y) : x(x), y(y) {} friend std::ostream operator(std::ostream os, const Vec2 v); }; std::ostream operator(std::ostream os, const Vec2 v) { return os ( v.x , v.y ); // 访问了 private }二、按“是不是特殊成员函数”划分存在C 标准C 标准里有一组叫“特殊成员函数”special member function编译器会自动生成或参与规则2.1 构造函数Constructor1默认构造函数class A { public: A() { } // 默认构造 };2带参数构造函数class A { public: A(int x, double y) { } };3委托构造函数class A { public: A() : A(0) {} // 委托给 A(int) A(int x) { } };2.2 拷贝构造函数Copy Constructorclass A { public: A(const A other) { // 拷贝构造 // 从 other 复制 } };在以下情况下调用A b a;按值传参 / 返回值等场景。2.3 移动构造函数Move Constructorclass A { public: A(A other) noexcept { // 移动构造 // 从 other“偷走”资源 } };在A b std::move(a);时调用。2.4 拷贝赋值运算符Copy Assignmentclass A { public: A operator(const A other) { // 拷贝赋值 if (this ! other) { // 释放原资源 拷贝 new } return *this; } };2.5 移动赋值运算符Move Assignmentclass A { public: A operator(A other) noexcept { // 移动赋值 if (this ! other) { // 释放原资源 偷走 other } return *this; } };2.6 析构函数Destructorclass A { public: ~A() { // 析构函数 // 释放资源 } };对象生命周期结束时自动调用。三、按“多态特性”划分普通 / 虚函数 / 纯虚函数3.1 普通成员函数没有virtual的正常成员函数。class Base { public: void foo() { std::cout Base::foo\n; } };3.2 虚函数virtual支持运行时多态。class Base { public: virtual void foo() { std::cout Base::foo\n; } }; class Derived : public Base { public: void foo() override { std::cout Derived::foo\n; } }; Base* p new Derived; p-foo(); // 调用 Derived::foo虚函数动态绑定3.3 纯虚函数pure virtualclass Shape { public: virtual void draw() 0; // 纯虚函数 };特点含纯虚函数的类是抽象类不能直接实例化。必须在子类中重写才能使用。四、按“修饰符”划分const / ref 限定 / noexcept / inline4.1 const 成员函数class Vec2 { public: double x, y; Vec2(double x 0, double y 0) : x(x), y(y) {} // 重载运算符成员函数版本 Vec2 operator(const Vec2 other) const { // 自定义“加法规则”x加xy加y return Vec2(x other.x, y other.y); } };含义函数体内不能修改成员除 mutable。this是const Vec2*。可以在const Vec2对象上调用。4.2 引用限定符成员函数 / 区分左值对象 / 右值对象调用。左值 能取地址、有名字的对象右值 临时对象、无名对象、即将被销毁的对象class Str { public: std::string data; std::string moveData() { // 只能用于右值 return std::move(data); } std::string getData() { // 只能用于左值 return data; } }; Str s; s.getData(); // OK左值对象 // s.moveData(); // ❌ 错误必须右值调用 Str().moveData(); // OK临时右值对象4.3 noexcept 函数承诺不会抛异常利于优化异常安全。void f() noexcept { // 不允许抛出异常 }4.4 inline 函数建议编译器内联不保证。定义在类内部的成员函数默认是 inline。inline int add(int a, int b) { return a b; } class A { public: void foo() { } // 默认 inline };五、按“编译期特性”划分模板 / constexpr / consteval5.1 函数模板Function Templatetemplatetypename T T add(T a, T b) { return a b; } int x add(1, 2); // 实例化 Tint double y add(1.5, 2.5); // 实例化 Tdouble5.2 constexpr 函数可用于常量表达式constexpr int sqr(int x) { return x * x; } constexpr int v sqr(5); // 编译期计算 int arr[sqr(3)]; // 数组大小也可以用5.3 consteval 函数必须在编译期算C20 引入。consteval int foo(int x) { return x * 2; } constexpr int v foo(10); // OK编译期 int x foo(10); // 也必须编译期就算好六、可调用对象扩展lambda / 函数对象 / 函数指针严格说这些不都是“用关键字function定义的函数”但在面试 工程中都算“函数类型家族”的一部分。6.1 Lambda 表达式auto add [](int a, int b) { return a b; }; int r add(1, 2);本质上编译器生成了一个匿名类重载operator()。6.2 函数对象仿函数struct Add { int operator()(int a, int b) const { return a b; } }; Add add; int r add(1, 2);STL 里大量使用如std::less、std::hash。6.3 函数指针 成员函数指针// 普通函数指针 int add(int a, int b) { return a b; } int (*pf)(int, int) add; // 成员函数指针 struct A { void foo(int) { } }; void (A::*pm)(int) A::foo; A obj; (obj.*pm)(42);七、总表C 函数“类型家族”一览分类轴类型示例说明归属非成员函数int add(int,int);不属于类全局/命名空间归属成员函数void foo();属于类有this归属静态成员函数static void init();无 this只能访问静态成员权限友元函数friend std::ostream operator(...)非成员但可访问 private特殊成员构造函数A(); A(int);创建对象特殊成员拷贝构造A(const A);复制对象特殊成员移动构造A(A);移动资源特殊成员析构函数~A();销毁对象特殊成员拷贝赋值A operator(const A);赋值拷贝特殊成员移动赋值A operator(A);移动赋值多态虚函数virtual void f();支持运行时多态多态纯虚函数virtual void f() 0;抽象接口修饰const 成员函数int get() const;不修改对象修饰ref 限定函数void f() ;区分左值/右值 this修饰noexceptvoid f() noexcept;承诺不抛异常修饰inlineinline int f();建议内联编译期函数模板templateclass T T add(T,T);类型参数化编译期constexpr 函数constexpr int f(int);可用于常量表达式编译期consteval 函数consteval int f(int);必须编译期执行可调用对象lambdaauto f [](...){};匿名仿函数可调用对象函数对象struct F { void operator()(); };自定义调用行为可调用对象函数指针void (*pf)();指向函数可调用对象成员函数指针void (C::*pm)();指向成员函数八、总结从“C 八股”角度看你可以说C 里的函数大体可以从 3 条线理解归属成员 / 静态成员 / 非成员 / 全局 / 友元行为普通 / const / static / virtual / 纯虚 / inline / noexcept 等编译期模板 / constexpr / consteval再加上 lambda、仿函数、函数指针就是基本完整的“可调用对象家族”。