C++基础 — 函数总结

一、函数核心作用

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

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. 析构函数不要手动调用,对象销毁自动执行

相关推荐
糖果店的幽灵2 小时前
langgraph的 MessagesState 解读
java·开发语言·人工智能·windows·langgraph
Fu_Lin_2 小时前
Qt 嵌入式从零基础到精通总纲
开发语言·qt·嵌入式·qt嵌入式
星空露珠3 小时前
28种颜色对应名称,
开发语言·数据库·算法·游戏·lua
码云数智-大飞3 小时前
PHP 接口开发规范:统一返回格式、异常处理与参数校验
开发语言·php
浮江雾3 小时前
Flutter第十七节-----路由管理(3)
android·开发语言·前端·javascript·flutter·入门
我不是懒洋洋3 小时前
从零实现一个分布式监控:Prometheus的核心设计
c++
admin and root3 小时前
「移动安全」安卓APP 反编译&frida脱壳技巧分享
android·开发语言·python·web安全·微信小程序·移动安全·攻防演练
dadaobusi3 小时前
仿真边界处理
开发语言·php
踏月的造梦星球4 小时前
DM8 DSC 单机双实例部署
运维·开发语言·数据库