C++ 函数编写与封装方法详解

1. 函数的基本结构

1.1 基本函数定义

1
2
3
4
5
6
7
8
// 函数声明
返回类型 函数名(参数列表);

// 函数定义
返回类型 函数名(参数列表) {
// 函数体
return 返回值;
}

1.2 完整示例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <iostream>
using namespace std;

// 函数声明
int add(int a, int b);
void printMessage(const string& message);

// 函数定义
int add(int a, int b) {
return a + b;
}

void printMessage(const string& message) {
cout << "Message: " << message << endl;
}

int main() {
int result = add(5, 3);
printMessage("Hello World");
return 0;
}

2. 参数传递方式

2.1 值传递 (Pass by Value)

1
2
3
4
5
6
7
8
9
void modifyValue(int x) {
x = 100; // 不影响原始变量
}

int main() {
int a = 10;
modifyValue(a);
cout << a; // 输出: 10
}

2.2 引用传递 (Pass by Reference)

1
2
3
4
5
6
7
8
9
void modifyReference(int &x) {
x = 100; // 修改原始变量
}

int main() {
int a = 10;
modifyReference(a);
cout << a; // 输出: 100
}

2.3 常量引用传递 (Pass by Const Reference)

1
2
3
4
5
6
void printLargeObject(const vector<int>& vec) {
// 可以读取但不能修改vec
for(const auto& item : vec) {
cout << item << " ";
}
}

2.4 指针传递 (Pass by Pointer)

1
2
3
4
5
6
7
8
9
10
11
void modifyPointer(int* ptr) {
if(ptr) {
*ptr = 100; // 解引用并修改值
}
}

int main() {
int a = 10;
modifyPointer(&a);
cout << a; // 输出: 100
}

3. 函数重载 (Function Overloading)

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 Calculator {
public:
// 重载add函数
int add(int a, int b) {
return a + b;
}

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

string add(const string& a, const string& b) {
return a + b;
}

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

// 使用示例
Calculator calc;
cout << calc.add(1, 2); // 调用int版本
cout << calc.add(1.5, 2.5); // 调用double版本
cout << calc.add("Hello", " World"); // 调用string版本

4. 默认参数 (Default Parameters)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
class Student {
public:
// 带有默认参数的构造函数
Student(string name = "Unknown", int age = 18, double gpa = 3.0)
: name(name), age(age), gpa(gpa) {}

void displayInfo(string prefix = "Student: ") {
cout << prefix << name << ", Age: " << age << ", GPA: " << gpa << endl;
}

private:
string name;
int age;
double gpa;
};

// 使用示例
Student s1; // 使用所有默认参数
Student s2("Alice"); // 只提供name
Student s3("Bob", 20); // 提供name和age
Student s4("Charlie", 22, 3.8); // 提供所有参数

5. 内联函数 (Inline Functions)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 内联函数 - 适合短小的函数
inline int square(int x) {
return x * x;
}

inline int max(int a, int b) {
return (a > b) ? a : b;
}

class MathUtils {
public:
// 类内定义的函数默认为内联
int cube(int x) {
return x * x * x;
}

// 显式声明内联
inline double circleArea(double radius) {
return 3.14159 * radius * radius;
}
};

6. 模板函数 (Template Functions)

6.1 基础模板函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
template<typename T>
T getMax(T a, T b) {
return (a > b) ? a : b;
}

template<typename T1, typename T2>
auto addMixed(T1 a, T2 b) -> decltype(a + b) {
return a + b;
}

// 使用示例
cout << getMax(10, 20); // int版本
cout << getMax(3.14, 2.71); // double版本
cout << getMax('a', 'z'); // char版本

6.2 模板特化

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
template<typename T>
class Storage {
public:
void store(const T& data) {
cout << "Storing generic type: " << data << endl;
}
};

// 模板特化 - 针对string类型
template<>
class Storage<string> {
public:
void store(const string& data) {
cout << "Storing string: \"" << data << "\"" << endl;
}
};

7. Lambda 表达式

7.1 基础Lambda

1
2
3
4
5
6
7
8
9
// 简单的lambda表达式
auto square = [](int x) { return x * x; };
auto greet = [](const string& name) {
return "Hello, " + name + "!";
};

// 使用示例
cout << square(5); // 输出: 25
cout << greet("World"); // 输出: Hello, World!

7.2 捕获列表

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
26
27
28
29
30
31
class LambdaDemo {
private:
int multiplier = 10;

public:
void demonstrate() {
int localVar = 5;

// 值捕获
auto captureByValue = [localVar](int x) {
return x + localVar; // 捕获时的localVar值
};

// 引用捕获
auto captureByReference = [&localVar](int x) {
localVar = x; // 修改原始localVar
return localVar;
};

// 捕获this指针
auto captureThis = [this](int x) {
return x * multiplier; // 访问成员变量
};

// 混合捕获
auto mixedCapture = [=, &localVar](int x) {
// 默认值捕获,但localVar是引用捕获
return x + localVar + multiplier;
};
}
};

8. 函数指针和函数对象

8.1 函数指针

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// 普通函数
int add(int a, int b) { return a + b; }
int multiply(int a, int b) { return a * b; }

// 函数指针类型
using MathOperation = int(*)(int, int);

class Calculator {
public:
int calculate(MathOperation op, int a, int b) {
return op(a, b);
}
};

// 使用示例
Calculator calc;
cout << calc.calculate(add, 5, 3); // 输出: 8
cout << calc.calculate(multiply, 5, 3); // 输出: 15

8.2 函数对象 (Functor)

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
26
27
class Adder {
private:
int baseValue;

public:
Adder(int base) : baseValue(base) {}

// 重载函数调用运算符
int operator()(int value) const {
return baseValue + value;
}
};

class Comparator {
public:
bool operator()(int a, int b) const {
return a > b; // 降序比较
}
};

// 使用示例
Adder add5(5);
cout << add5(10); // 输出: 15

vector<int> numbers = {3, 1, 4, 1, 5};
sort(numbers.begin(), numbers.end(), Comparator());
// numbers变为: 5, 4, 3, 1, 1

9. 成员函数封装

9.1 类的基本封装

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
26
27
28
29
30
31
32
33
34
35
36
37
class BankAccount {
private:
string accountNumber;
double balance;

// 私有辅助函数
bool isValidAmount(double amount) const {
return amount > 0;
}

public:
// 构造函数
BankAccount(const string& accNum, double initialBalance = 0.0)
: accountNumber(accNum), balance(initialBalance) {}

// Getter函数
string getAccountNumber() const { return accountNumber; }
double getBalance() const { return balance; }

// 业务逻辑函数
bool deposit(double amount) {
if(!isValidAmount(amount)) return false;
balance += amount;
return true;
}

bool withdraw(double amount) {
if(!isValidAmount(amount) || amount > balance) return false;
balance -= amount;
return true;
}

// 静态成员函数
static string getBankName() {
return "MyBank";
}
};

9.2 接口和实现分离

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
26
27
28
29
30
// 头文件: math_interface.h
class IMathOperations {
public:
virtual ~IMathOperations() = default;
virtual double calculate(double a, double b) = 0;
virtual string getName() const = 0;
};

// 源文件: math_implementations.cpp
class Addition : public IMathOperations {
public:
double calculate(double a, double b) override {
return a + b;
}

string getName() const override {
return "Addition";
}
};

class Multiplication : public IMathOperations {
public:
double calculate(double a, double b) override {
return a * b;
}

string getName() const override {
return "Multiplication";
}
};

10. 现代C++特性

10.1 constexpr 函数

1
2
3
4
5
6
7
8
9
10
11
12
// 编译时计算函数
constexpr int factorial(int n) {
return (n <= 1) ? 1 : n * factorial(n - 1);
}

constexpr int fibonacci(int n) {
return (n <= 1) ? n : fibonacci(n - 1) + fibonacci(n - 2);
}

// 使用示例
constexpr int fact5 = factorial(5); // 编译时计算
constexpr int fib10 = fibonacci(10); // 编译时计算

10.2 noexcept 函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
class SafeCalculator {
public:
// 保证不抛出异常的函数
int safeDivide(int a, int b) noexcept {
if(b == 0) return 0; // 处理除零,不抛出异常
return a / b;
}

// 条件noexcept
template<typename T>
void processData(T&& data) noexcept(noexcept(data.process())) {
data.process();
}
};

11. 错误处理和异常安全

11.1 异常处理

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
26
27
28
29
30
class FileProcessor {
public:
void processFile(const string& filename) {
ifstream file(filename);
if(!file.is_open()) {
throw runtime_error("Cannot open file: " + filename);
}

try {
// 文件处理逻辑
string line;
while(getline(file, line)) {
processLine(line);
}
}
catch(const exception& e) {
// 清理资源
file.close();
throw; // 重新抛出异常
}
}

private:
void processLine(const string& line) {
if(line.empty()) {
throw invalid_argument("Empty line encountered");
}
// 处理行内容
}
};

最佳实践总结

  1. 单一职责原则:每个函数只做一件事
  2. 合理的参数传递:小对象传值,大对象传const引用
  3. 清晰的命名:函数名应该明确表达其功能
  4. 适当的封装:使用private保护内部状态
  5. 异常安全:确保资源正确释放
  6. 文档注释:为公共接口提供清晰的文档
  7. 测试覆盖:为关键函数编写单元测试

这些方法可以帮助你编写出更清晰、更安全、更易维护的C++代码。