【C++进阶】函数:深度解析 C++ 函数的 12 大进化特性

目录

一、函数基础

1.1 函数定义与声明

1.2 函数调用

1.3 引用参数

二、函数重载:同名函数的「多态魔法」(C++ 特有)

2.1 基础实现

2.2 重载决议流程图

2.3 与 C 语言的本质区别

2.4 实战陷阱

三、默认参数:接口的「弹性设计」(C++ 特有)

3.1 语法规则

3.2 C 语言替代方案(笨拙且易错)

四、内联函数:性能与代码的「平衡艺术」

4.1 C++ vs C 的内联差异

4.2 现代 C++ 实践(C++17)

4.3. 内联函数示例

4.4 注意事项

五、constexpr 函数:编译期计算的「常量革命」(C++11+)

5.1 基础用法

5.2 与 C 宏的本质区别

5.3 实战案例:编译期斐波那契数列 

六、lambda 表达式:匿名函数的「编程解放」(C++11+)

6.1 基础语法

6.2 捕获方式对比

6.3 与 C 函数指针的对比

6.4 Lambda表达式示例 

七、函数模板:泛型编程的「基石」

7.1 基础实现

7.2 模板特化(Partial Specialization)

八、成员函数:类的「行为封装」(C++ 特有)

8.1 成员函数分类

8.2 虚函数:多态的核心 

8.3 const 成员函数:数据安全的保障

九、异常规范:错误处理的「契约式设计」

9.1 现代 C++ 实践(noexcept)

9.2 与 C 语言的对比

十、尾随返回类型:类型推导的「语法革命」(C++11+)

10.1 基础用法

 10.2 复杂类型示例

十一、初始化捕获:lambda 的「状态封装」(C++14+)

11.1 语法创新

11.2 与 C 语言的对比

十二、友元函数:打破封装的「双刃剑」(C++ 特有)

12.1 基础用法

12.2 友元模板

十三、函数指针进化:从过程到对象的「寻址革命」

13.1 成员函数指针

13.2 与 C 语言函数指针的对比

十四、C++20 新特性:函数的「终极进化」

14.1 协同函数(Coroutine)

十五、最佳实践与性能优化

15.1 重载决议优化

15.2 lambda 性能优化

15.3 成员函数设计原则

十六、总结:C++ 函数的「编程范式跃迁」

十七、参考资料


C 语言的函数是面向过程的「子程序」,而 C++ 的函数是面向对象和泛型编程的「一等公民」。本文将通过12 个核心特性,通过与C语言的对比分析,重点讲解C++在函数设计上的改进与创新。

一、函数基础

在C和C++中,函数都是实现代码复用的重要手段。函数允许将一段代码封装起来,通过函数名进行调用,从而提高代码的可读性和可维护性。

1.1 函数定义与声明

在C语言中,函数的定义和声明通常如下所示:

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

在C++中,函数的定义和声明与C语言非常相似,但C++允许函数具有更复杂的类型系统,例如返回类型和参数类型可以是用户自定义的类型。

#include <iostream>// 用户自定义类型:二维点
struct Point {int x;int y;// 成员函数示例void print() {std::cout << "(" << x << ", " << y << ")\n";}
};// 函数声明(参数和返回类型均为自定义类型)
Point addPoints(const Point& a, const Point& b);int main() {// 创建自定义类型对象Point p1 = {1, 2};Point p2 = {3, 4};// 调用自定义类型参数的函数Point result = addPoints(p1, p2);// 使用自定义类型的成员函数result.print();  // 输出:(4, 6)return 0;
}// 函数定义(实现细节)
Point addPoints(const Point& a, const Point& b) {Point sum;sum.x = a.x + b.x;sum.y = a.y + b.y;return sum;
}

1.2 函数调用

函数调用在C和C++中都是相同的,通过函数名和参数列表来调用函数。

// C语言中的函数调用
int result = add(3, 4);
// C++中的函数调用
int result = add(3, 4);

1.3 引用参数

C++引入引用类型作为更安全的指针替代方案:

#include <iostream>void swap(int& a, int& b) {int temp = a;a = b;b = temp;
}int main() {int x = 10, y = 20;std::cout << "Before: x=" << x << ", y=" << y << std::endl;swap(x, y);std::cout << "After:  x=" << x << ", y=" << y << std::endl;return 0;
}

引用 vs 指针:

特性引用指针
空值不能为NULL可以为NULL
重定义不可可以
地址操作自动解引用显式操作
语法简洁性

二、函数重载:同名函数的「多态魔法」(C++ 特有)

函数重载是C++相对于C语言的一个重要特性。它允许在同一作用域内定义多个同名函数,但这些函数的参数类型或参数个数必须不同。编译器会根据函数调用时提供的参数类型和个数来确定调用哪个函数。

2.1 基础实现

#include <iostream>// C++支持重载,C语言禁止
void print(int x) { std::cout << "int: " << x << '\n'; }
void print(double x) { std::cout << "double: " << x << '\n'; }
void print(const char* s) { std::cout << "string: " << s << '\n'; }int main() {print(42);       // int: 42print(3.14);     // double: 3.14print("Hello");  // string: Hello
}

2.2 重载决议流程图

2.3 与 C 语言的本质区别

特性C++C 语言
同名函数支持(参数列表不同)禁止(链接错误)
编译机制名称改编(Name Mangling)直接使用函数名
错误检查编译期类型安全检查仅检查参数数量(弱类型)

2.4 实战陷阱

void f(int x, int y = 0); // 声明带默认参数
void f(int x, int y);    // 定义不带默认参数(C++允许,但调用时按声明处理)

三、默认参数:接口的「弹性设计」(C++ 特有)

C++允许在函数定义或声明时为参数指定默认值。当调用函数时,如果未提供具有默认值的参数,则使用默认值。

3.1 语法规则

#include <iostream>
using namespace std;// 定义函数,为参数b和c指定默认值
int add(int a, int b = 5, int c = 10) {return a + b + c;
}int main() {cout << "add(3) = " << add(3) << endl;       // 使用默认值:b=5, c=10cout << "add(3, 7) = " << add(3, 7) << endl;  // 使用默认值:c=10cout << "add(3, 7, 2) = " << add(3, 7, 2) << endl; // 不使用默认值return 0;
}

 

注意事项:

  • 默认参数只能在函数声明或定义时指定一次:不能在函数声明和定义时分别为同一个参数指定默认值。

  • 默认参数应从右往左连续指定:如果为某个参数指定了默认值,则它右边的所有参数也必须具有默认值。

3.2 C 语言替代方案(笨拙且易错)

// C语言通过宏模拟默认参数
#define SET_CONFIG(port, host) set_config((port) ? (port) : 8080, (host) ? (host) : "localhost")
void set_config(int port, const char* host); // 无默认参数

四、内联函数:性能与代码的「平衡艺术」

内联函数是C++中用于提高函数调用效率的一种机制。通过将函数体在调用点展开(内联展开),可以减少函数调用的开销(如栈帧的创建和销毁、参数传递等)。

4.1 C++ vs C 的内联差异

特性C++C 语言(C99+)
关键字inlinestatic inline(文件作用域)
链接属性可跨文件(需同名定义)静态(文件内)
编译器控制建议性(可能被忽略)强制展开(函数体必须简单)

4.2 现代 C++ 实践(C++17)

// 强制内联(GCC/Clang扩展)
[[gnu::always_inline]] 
void fast_math(float& x) { x *= 1.618f; } // 高频调用的数学函数

4.3. 内联函数示例

#include <iostream>
using namespace std;// 使用inline关键字声明内联函数
inline int max(int a, int b) {return (a > b) ? a : b;
}int main() {cout << "max(3, 4) = " << max(3, 4) << endl;return 0;
}

inline关键字只是向编译器提出一个请求,编译器可以选择忽略这个请求。因此,即使使用了inline关键字,也不能保证函数一定会被内联展开。

4.4 注意事项

  • 内联函数通常适用于短小且频繁调用的函数:对于大型或复杂的函数,内联展开可能会增加代码体积并降低性能。

  • 内联函数在类定义中自动成为内联函数:在类定义中定义的成员函数(包括成员函数声明和定义)自动成为内联函数,无需使用inline关键字。

  • 编译器可能会对内联函数进行优化:即使函数被内联展开,编译器也可能会对生成的代码进行优化以提高性能。

、constexpr 函数:编译期计算的「常量革命」(C++11+)

5.1 基础用法

constexpr int square(int x) { return x * x; } // 编译期计算
constexpr auto arr = {square(2), square(3)}; // 编译期初始化数组

5.2 与 C 宏的本质区别

特性constexpr 函数C 宏
类型安全严格类型检查无类型(可能导致副作用)
调试信息保留函数名和行号宏展开后难以追踪
递归支持支持编译期递归不支持

5.3 实战案例:编译期斐波那契数列 

constexpr int fib(int n) {return n <= 1 ? n : fib(n-1) + fib(n-2); // 编译期计算
}
constexpr int fib_42 = fib(42); // 编译期完成计算

六、lambda 表达式:匿名函数的「编程解放」(C++11+)

C++11引入了Lambda表达式,允许在代码中定义匿名函数对象。Lambda表达式提供了一种简洁而强大的方式来定义和使用短小的函数对象。

6.1 基础语法

// [捕获列表](参数列表) mutable? exception? -> 返回类型 { 函数体 }
auto add = [](int a, int b) { return a + b; };
std::cout << add(3, 5); // 8

6.2 捕获方式对比

捕获方式说明示例
空捕获不捕获任何变量[]{}
值捕获拷贝变量值(默认 const)[x]{ return x*2; }
引用捕获引用变量(需确保生命周期)[&y]{ y++; }
混合捕获部分值 / 部分引用[x, &y]{ return x + y; }
初始化捕获C++14,任意表达式初始化[a=1, b=std::move(vec)]{}

6.3 与 C 函数指针的对比

// C语言:通过函数指针实现回调
void (*callback)(int);
callback = &handle_event;// C++:lambda直接捕获上下文
std::vector<int> data = {1,2,3};
std::for_each(data.begin(), data.end(), [&](int x) {std::cout << x * data.size(); // 直接捕获data
});

6.4 Lambda表达式示例 

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;int main() {vector<int> vec = {1, 2, 3, 4, 5};// 使用Lambda表达式对vector中的元素进行排序(降序)sort(vec.begin(), vec.end(), [](int a, int b) {return a > b;});// 输出排序后的vectorfor (int n : vec) {cout << n << " ";}cout << endl;return 0;
}

七、函数模板:泛型编程的「基石」

7.1 基础实现

template <typename T>
T max(T a, T b) { return a > b ? a : b; }int main() {std::cout << max(5, 3);    // intstd::cout << max(3.14, 2.71); // double
}

7.2 模板特化(Partial Specialization)

// 特化指针版本
template <typename T>
T* max(T* a, T* b) { return *a > *b ? a : b; }// 特化字符串版本
template <>
const char* max(const char* a, const char* b) {return std::strcmp(a, b) > 0 ? a : b;
}

八、成员函数:类的「行为封装」(C++ 特有)

8.1 成员函数分类

8.2 虚函数:多态的核心 

class Shape {
public:virtual double area() const = 0; // 纯虚函数
};class Circle : public Shape {
public:double area() const override { return M_PI * r * r; }
};

8.3 const 成员函数:数据安全的保障

class Data {
private:int value;
public:int get() const { return value; } // 保证不修改成员void set(int v) { value = v; }
};

九、异常规范:错误处理的「契约式设计」

9.1 现代 C++ 实践(noexcept)

// 声明不抛异常(C++11)
void critical_operation() noexcept {// 若抛出异常,调用std::terminate()
}// 有条件不抛异常
void safe_operation() noexcept(std::is_integral_v<Param>) {// 仅当Param为整数类型时不抛异常
}

9.2 与 C 语言的对比

特性C++C 语言
错误处理异常机制(try/catch/throw)返回错误码或全局错误变量(errno)
错误传播栈展开(Stack Unwinding)依赖函数调用链检查返回值
性能无异常时零开销始终检查返回值(潜在性能损失)

十、尾随返回类型:类型推导的「语法革命」(C++11+)

10.1 基础用法

// 传统写法(需前置声明)
template <typename T, typename U>
auto add(T t, U u) -> decltype(t + u) {return t + u;
}// C++14简化(自动推导)
template <typename T, typename U>
auto add(T t, U u) {return t + u;
}

 10.2 复杂类型示例

// 返回指向成员函数的指针
auto get_fun() -> int (Data::*)() const {return &Data::get;
}

十一、初始化捕获:lambda 的「状态封装」(C++14+)

11.1 语法创新

int base = 10;
auto adder = [a = base + 10](int x) { return a + x; };
std::cout << adder(5); // 25(a=20)

11.2 与 C 语言的对比

// C语言需手动封装状态
typedef struct { int base; } Adder;
int add(Adder* self, int x) { return self->base + x; }
Adder adder = { .base = 20 };
add(&adder, 5); // 25(需显式传递状态)

十二、友元函数:打破封装的「双刃剑」(C++ 特有)

12.1 基础用法

class Data {friend void print(const Data& d); // 友元声明
private:int value;
};void print(const Data& d) { // 访问私有成员std::cout << "Value: " << d.value << '\n';
}

12.2 友元模板

template <typename T>
class Container {friend T; // 授予整个类友元权限friend void debug(Container<T>& c); // 授予特定函数权限
};

十三、函数指针进化:从过程到对象的「寻址革命」

13.1 成员函数指针

class Data {
public:void print() const { std::cout << value << '\n'; }int value;
};int main() {Data d{42};void (Data::*mem_fn)() const = &Data::print;(d.*mem_fn)(); // 42(调用成员函数)
}

13.2 与 C 语言函数指针的对比

特性C++ 成员函数指针C 语言函数指针
绑定对象必须关联类对象独立于数据(面向过程)
语法&Class::member&function
调用方式obj.*mem_fn() 或 ptr->*mem_fn()fn()

十四、C++20 新特性:函数的「终极进化」

14.1 协同函数(Coroutine)

#include <coroutine>struct Generator {struct promise_type {int current_value = 0;Generator get_return_object() { return Generator{this}; }std::suspend_always yield_value(int value) {current_value = value;return {};}std::suspend_void return_void() { return {}; }};// ... 其他实现 ...
};Generator countdown(int n) {for (; n >= 0; --n) co_yield n;
}// 使用协同函数
for (int x : countdown(5)) {std::cout << x << ' '; // 5 4 3 2 1 0
}

十五、最佳实践与性能优化

15.1 重载决议优化

// 优先匹配非模板函数
void print(int x) { /* 特化实现 */ }
template <typename T> void print(T x) { /* 通用实现 */ }

15.2 lambda 性能优化

// 避免不必要的捕获
auto processor = [=](int x) mutable noexcept { /* 无堆分配的轻量级lambda */ };

15.3 成员函数设计原则

class Resource {
public:void use() const noexcept { /* 无修改的常量成员 */ }~Resource() = default; // 遵循Rule of Zero
};

十六、总结:C++ 函数的「编程范式跃迁」

特性C 语言C++价值定位
函数重载不支持支持(编译期多态)接口统一化
默认参数不支持支持(接口弹性)减少重复代码
lambda 表达式不支持支持(匿名函数 + 状态捕获)函数式编程支持
成员函数结构体 + 函数指针模拟原生支持(封装 / 继承 / 多态)面向对象基础
函数模板不支持支持(泛型编程)类型安全的代码复用
constexpr不支持支持(编译期计算)性能与安全性的双重提升

编程哲学:C++ 函数不仅是代码块,更是类型系统的延伸抽象机制的载体运行时与编译时的桥梁。掌握这些特性,方能驾驭现代 C++ 的三大范式(面向对象、泛型、函数式)。

十七、参考资料

  •  《C++ Primer(第 5 版)》这本书是 C++ 领域的经典之作,对 C++ 的基础语法和高级特性都有深入讲解。
  • 《Effective C++(第 3 版)》书中包含了很多 C++ 编程的实用建议和最佳实践。
  • 《C++ Templates: The Complete Guide(第 2 版)》该书聚焦于 C++ 模板编程,而using声明在模板编程中有着重要应用,如定义模板类型别名等。
  • C++ 官方标准文档:C++ 标准文档是最权威的参考资料,可以查阅最新的 C++ 标准(如 C++11、C++14、C++17、C++20 等)文档。例如,ISO/IEC 14882:2020 是 C++20 标准的文档,可从相关渠道获取其详细内容。
  • cppreference.com:这是一个非常全面的 C++ 在线参考网站,提供了详细的 C++ 语言和标准库文档。
  • LearnCpp.com:该网站提供了系统的 C++ 教程,配有丰富的示例代码和清晰的解释,适合初学者学习和理解相关知识。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/38468.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

spring boot 登入权限RBAC模式

首先准备好5张表 user_info表&#xff0c;用户的信息表 role表&#xff0c;角色表&#xff08;比如超级管理员、管理员、审核员、采购......&#xff09; 创建user_role表&#xff0c;user_info表&#xff0c;role表的中间表 注意了&#xff0c;role_id和user_id是 u…

C#里使用libxl来对列或行进行分组显示

有时候由于EXCEL里的行数很多, 需要把某些行进行隐藏起来,那么就需要使用到行或列进行隐藏的操作。 这时候需要使用函数GroupCols和GroupRows来对这些列或行进行分组。 分组不能出现交叉的情况,否则会抛出异常。 如下图所示: 可以使用下面的代码来输出上面的EXCEL: p…

LangChain 基础

一、LangChain 模块和体系 LangChain 是一个用于开发由大型语言模型&#xff08;LLMs&#xff09;驱动的应用程序的框架。 官方文档&#xff1a;https://python.langchain.com/docs/introduction/ LangChain 简化了LLM应用程序生命周期的每个阶段&#xff1a; 开发&#xf…

IDEA 快捷键ctrl+shift+f 无法全局搜索内容的问题及解决办法

本篇文章主要讲解IDEA、phpStrom、webStrom、pyCharm等jetbrains系列编辑器无法进行全局搜索内容问题的主要原因及解决办法。 日期&#xff1a;2025年3月22日 作者&#xff1a;任聪聪 现象描述&#xff1a; 1.按下ctrlshiftf 输入法转为了繁体。 2.快捷键ctrlshiftr 可以全局检…

2025年- G24-Lc98-217.包含重复(使用hashSet解决)-java版

1.题目描述 2.思路 思路一&#xff1a; 我的想法是直接用集合来判断&#xff0c;如果集合的元素不能添加说明之前已经存在这个元素&#xff0c;也就是发现了重复元素&#xff0c;所以返回false。 补充一&#xff1a; Map、ArrayList的定义和声明 3.代码实现 class Soluti…

MySQL事务全解析:从概念到实战

在数据库操作中&#xff0c;事务是一个至关重要的概念&#xff0c;它确保了数据的完整性和一致性。今天&#xff0c;就让我们深入探讨MySQL事务的方方面面&#xff0c;从基础概念到实际应用&#xff0c;全面掌握这一技能。 一、为什么需要事务 假设张三要给李四转账100元&…

CVPR 2025 | 文本和图像引导的高保真3D数字人高效生成GaussianIP

小小宣传一下CVPR 2025的工作GaussianIP。 arXiv&#xff1a;https://arxiv.org/abs/2503.11143 Github&#xff1a;https://github.com/silence-tang/GaussianIP 欢迎star, issue~ 摘要 文本引导的3D人体生成随着高效3D表示及2D升维方法&#xff08;如SDS&#xff09;的发展…

Model Context Protocol:下一代AI系统集成范式革命

在2023年全球AI工程化报告中,开发者面临的核心痛点排名前三的分别是:模型与业务系统集成复杂度(58%)、上下文管理碎片化(42%)、工具调用标准化缺失(37%)。传统API集成模式在对接大语言模型时暴露明显短板:RESTful接口无法承载动态上下文,GraphQL缺乏工具编排能力,gR…

多模态大模型常见问题

1.视觉编码器和 LLM 连接时&#xff0c;使用 BLIP2中 Q-Former那种复杂的 Adaptor 好还是 LLaVA中简单的 MLP 好&#xff0c;说说各自的优缺点&#xff1f; Q-Former&#xff08;BLIP2&#xff09;&#xff1a; 优点&#xff1a;Q-Former 通过查询机制有效融合了视觉和语言特征…

EasyRTC轻量级Webrtc音视频通话SDK,助力带屏IPC在嵌入式设备中的应用

一、市场背景 随着人们生活水平的提高&#xff0c;对于家居安全和远程监控的需求日益增长&#xff0c;带屏IPCam不仅满足了用户实时查看监控画面的需求&#xff0c;还提供了诸如双向语音通话、智能报警等丰富的功能&#xff0c;极大地提升了用户体验。 此外&#xff0c;技术的…

Linux安装JDK

1、下载JDK https://www.oracle.com/cn/java/technologies/downloads/#java11 2、安装 2.1、创建安装目录 mkdir /usr/local/jdk 2.1、将下载的tar.gz上传到服务器 使用tar -zxvf jdk-8u311-linux-x64.tar.gz解压后剪切到 /usr/local/jdk目录&#xff1a;mv xxx /usr/local/j…

基于基于eFish-SBC-RK3576工控板的智慧城市边缘网关

此方案充分挖掘eFish-SBC-RK3576的硬件潜力&#xff0c;可快速复制到智慧园区、交通枢纽等场景。 方案亮点 ‌接口高密度‌&#xff1a;单板集成5GWiFi多路工业接口&#xff0c;减少扩展复杂度。‌AIoT融合‌&#xff1a;边缘端完成传感器数据聚合与AI推理&#xff0c;降低云端…

CSS 学习笔记 - 蓝桥杯重点整理

1. CSS 基础语法 核心知识点 选择器 声明块结构三种引入方式&#xff1a;行内/内部/外部常用选择器类型&#xff1a;标签/类/ID/通配符 <!-- 行内样式 --> <p style"color: red;">红色文字</p><!-- 内部样式 --> <style>/* 标签选…

UML的使用

process on 在线使用 UML概念 UML &#xff1a;统一建模语言(Unified Modeling Language&#xff0c;是用来设计软件的可视化建模语言。 1. 类图 1.1 概念 类图&#xff08;Class Diagram&#xff09;是UML中用于描述系统静态结构的图形化工具。它展示了系统的类、接口、它…

【C++】入门

1.命名空间 1.1 namespace的价值 在C/C中&#xff0c;变量&#xff0c;函数和后面要学到的类都是大量存在的&#xff0c;这些变量&#xff0c;函数和类的名称将存在于全局作用域中&#xff0c;可能会导致很多冲突。使用命名空间的目的是对标识符的名称进行本地化&#xff0c;…

数据库练习2

目录 1.向heros表中新增一列信息&#xff0c;添加一些约束&#xff0c;并尝试查询一些信息 2.课堂代码练习 插入语句 INSERT INTO 删除语句DELETE和TRUNCATE 更新语句UPDATE和replace 查询语句SELECT 条件查询 查询排序 聚合函数 分组查询 3.题目如下 一、单表查询 …

w266农产品直卖平台的设计与实现

&#x1f64a;作者简介&#xff1a;多年一线开发工作经验&#xff0c;原创团队&#xff0c;分享技术代码帮助学生学习&#xff0c;独立完成自己的网站项目。 代码可以查看文章末尾⬇️联系方式获取&#xff0c;记得注明来意哦~&#x1f339;赠送计算机毕业设计600个选题excel文…

2025新版懒人精灵零基础安装调试+lua基础+UI设计交互+常用方法封装+项目实战+项目打包安装板块-视频教程(初学者必修课)

2025新版懒人精灵零基础安装调试lua基础UI设计交互常用方法封装项目实战项目打包安装板块-视频教程(初学者必修课)&#xff1a; 1.懒人精灵核心API基础和lua基础视频教程&#xff1a;https://www.bilibili.com/video/BV1Vm9kYJEfM/ 温馨提示&#xff1a;所有视频请用电脑浏览…

CCF-CSP认证 202206-2寻宝!大冒险!

题目描述 思路 有一张绿化图和藏宝图&#xff0c;其中绿化图很大&#xff08;二维数组在限定的空间内无法存储&#xff09;&#xff0c;而藏宝图是绿化图中的一部分&#xff0c;对于绿化图和藏宝图&#xff0c;左下角的坐标为(0, 0)&#xff0c;右上角的坐标是(L, L)、(S, S)&…

Qt下集成大华网络相机SDK示例开发

文章目录 前言一、下载并集成大华网络相机SDK二、示例实现功能三、示例完整代码四、下载链接总结 前言 近期在Qt环境下进行大华网络相机的使用&#xff0c;发现官网下载的SDK中提供的示例没有Qt的demo&#xff0c;通过学习其提供的MFC示例代码&#xff0c;我在这里也实现了一个…