C++基础 — 函数总结
2026/7/24 12:53:15 网站建设 项目流程

一、函数核心作用

把一段重复、独立的逻辑封装起来,一次定义、多处调用,实现代码复用、逻辑分层、降低维护成本。

C++函数分为:普通全局函数、类成员函数(构造/析构/普通成员/静态成员/常函数)、内联函数、模板函数、Lambda匿名函数。


二、函数基础语法

1. 完整结构

// 返回值类型 函数名(参数列表) { 函数体; return 返回值; } int add(int a, int b) { return a + b; }

1. 返回值类型:函数执行完返回的数据类型;无返回写 void

2. 函数名:标识符,见名知意,不能是关键字

3. 参数列表:0个/多个,逗号分隔;形参(定义处)、实参(调用处)

4. 函数体:大括号内执行逻辑

5. return:终止函数,带回返回值;void函数可省略 return

2. 无参、无返回示例

void printHello() { std::cout << "Hello C++" << std::endl; } // 调用 printHello();

3. 有参有返回

double mul(double x, double y) { return x * y; } double res = mul(3.14, 2);

三、函数声明 vs 函数定义(对应.h/.cpp)

1. 声明(只告诉编译器函数长什么样,无实现)

放在头文件 .h,作用:提前告知接口,解决“调用在定义前”报错。语法:末尾加分号。

// 声明 int add(int a, int b);

2. 定义(完整实现逻辑)

放在 .cpp,只能定义一次。

int add(int a, int b) { return a + b; }

工程规范:

.h:放函数声明

.cpp:#include 对应头文件,写函数实现


四、函数参数四大传递方式

1. 值传递(拷贝,最常用)

实参拷贝一份给形参,函数内修改形参不影响外部变量。

void test(int x) { x = 100; // 只改副本 } int a = 10; test(a); // a 依旧是 10

缺点:大对象(string、类)拷贝开销大。

2. 引用传递 & 常引用(&/const&)

(1)普通引用 T&

形参是实参别名,修改形参直接改外部变量,无拷贝开销。

void modify(int& x) { x = 999; } int num = 10; modify(num); // num = 999

(2)const 常引用 const T&(最优传参)

只读取、不修改,无拷贝、不能改原数据,传递字符串/类首选。

void showStr(const std::string& s) { std::cout << s; // s = "xxx"; // 报错,const 不可修改 }

3. 指针传递 T*

传递变量地址,通过解引用修改原值,兼容C语言。

void setVal(int* p) { *p = 666; } int n = 1; setVal(&n);

4. 数组参数

数组传参等价于指针,会丢失长度,需额外传大小。

void printArr(int arr[], int len) { for (int i = 0; i < len; i++) std::cout << arr[i]; }

五、默认参数

定义函数时给参数预设值,调用不传则使用默认值。规则:带默认值的参数必须靠右。

// 正确:默认参数放后面 void func(int a, int b = 10, double c = 3.14) {} // 调用多种写法 func(1); // b=10, c=3.14 func(1, 20); // c=3.14 func(1, 20, 9.9); // 错误:默认参数不能靠左 // void func(int a = 10, int b) // 编译报错

注意:声明和定义只能一处写默认值,推荐写在 .h 声明里。


六、函数重载 Overload

同一作用域,函数名相同,参数列表不同(个数/类型/顺序),编译器自动匹配对应函数。返回值不能作为重载区分依据。

// 重载1 int calc(int a) { return a; } // 重载2 int calc(int a, int b) { return a + b; } // 重载3 double calc(double a) { return a * 2; } calc(10); // 调用重载1 calc(1, 2); // 调用重载2 calc(2.5); // 调用重载3

Qt 中大量使用重载(按钮点击、控件构造)。


七、特殊函数:类内成员函数

1. 构造函数 Constructor

函数名=类名,无返回值,可重载。创建对象自动调用,用于初始化成员变量。

class Person { public: Person() { // 无参构造 age = 0; } Person(int a) { // 有参构造(重载) age = a; } private: int age; }; Person p1; // 调用无参构造 Person p2(18); // 调用有参构造

2. 析构函数 Destructor ~类名()

如:~MainWindow()

波浪号~+类名,无参数、无返回、只能一个。对象销毁时自动调用,释放堆内存、资源、句柄。

class MainWindow { public: MainWindow(); ~MainWindow(); // 析构 };

3. 常成员函数 const

函数末尾加 const,函数内不能修改成员变量,只能读取。

class Test { public: int getNum() const { // num = 10; // 报错 return num; } private: int num = 5; };

4. 静态成员函数 static

属于类,不属于单个对象,只能访问静态成员,没有 this 指针。

class Math { public: static int max(int a, int b) { return a > b ? a : b; } }; // 直接类名调用,不用创建对象 Math::max(3, 9);

八、内联函数 inline

普通函数调用有压栈跳转开销,inline 提示编译器将函数代码直接嵌入调用处,省去调用开销。适用:代码很短(1~5行)、频繁调用的函数。

inline int square(int x) { return x * x; }

模板函数默认隐式 inline,必须写在头文件。


九、模板函数 template

通用函数,适配任意数据类型,解决重复写 int/double/string 同款逻辑。

template<typename T> T add(T a, T b) { return a + b; } add<int>(1, 2); // 返回 3 add<double>(1.1, 2.2); // 返回 3.3

强制放 .h 头文件,编译器需要完整定义才能实例化。


十、Lambda 匿名函数 C++11+

不用定义函数名,临时写一段逻辑,常用于 Qt 信号槽、排序、遍历。

auto func = [](int x) -> int { return x * 2; }; std::cout << func(5); // 输出 10

捕获列表 []:[=] 值捕获、[&] 引用捕获外部变量。


十一、函数递归

函数内部自己调用自己,必须有终止条件,否则死循环栈溢出。

// 阶乘 int fact(int n) { if (n <= 1) return 1; // 终止条件 return n * fact(n - 1); }

十二、返回值补充

1. void:无返回,可写 return; 提前退出

2. 引用返回 int&:可以作为左值修改原变量

3. 指针返回 int*:返回堆地址,记得外部释放

4. 函数不能返回局部普通变量的引用/指针(局部变量销毁,悬空引用)


十三、常见易错点

1. 函数声明加分号,定义不能加分号

2. 模板、inline 放头文件;普通实现放 .cpp

3. 重载只看参数,返回值不算区分条件

4. 默认参数从右往左写

5. 传大型对象优先 const&,减少拷贝

6. 析构函数不要手动调用,对象销毁自动执行

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询