欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 文旅 > 游戏 > C++11QT复习 (十三)

C++11QT复习 (十三)

2025/4/3 14:30:16 来源:https://blog.csdn.net/m0_49013185/article/details/146935936  浏览:    关键词:C++11QT复习 (十三)

Day8-3 C++模板编程(2025.03.31)


1. 模板基础概念

模板类型

  1. 函数模板(生成模板函数)
  2. 类模板(生成模板类)
  3. 变量模板(C++14引入)

核心特点

  • 编译期代码生成
  • 类型安全的多态
  • 减少代码重复

2 .函数模板详解

基本语法

template <typename T>  // 或 template <class T>
T max(T a, T b) {return a > b ? a : b;
}

使用示例

void template_demo() {cout << max(1, 2);          // 类型推导cout << max<double>(1.5, 2); // 显式指定类型
}

数组处理技巧

template <typename T, size_t N>
void printArray(T (&arr)[N]) {for (size_t i = 0; i < N; ++i) {cout << arr[i] << " ";}
}

3. 类模板实战

基本实现

template <class T, size_t SIZE>
class MyArray {
public:T& operator[](size_t index) {return data[index];}
private:T data[SIZE];
};

标准库对比

void array_compare() {MyArray<int, 5> myArr;std::array<int, 5> stdArr;  // 更完善的实现
}

4 .模板高级特性

类型别名

template<typename T>
using Vec = std::vector<T>;Vec<int> v;  // 等价于 std::vector<int>

非类型模板参数

template<int N>
struct Factorial {static const int value = N * Factorial<N-1>::value;
};template<>
struct Factorial<0> {static const int value = 1;
};

**完整代码示例 **

#include <functional>
#include <algorithm>
#include <array>
#include <iostream>/*
模板模板的内容非常多,是类的好多倍,这里只做了解
感兴趣可以阅读《C++程序设计语言》有关模板的章节(比《C++ Primer》详细),足够掌握基本的模板用法
如果想成为模板专家,请阅读《C++ templates 第二版》,提供了所有的细节写好模板更多的是奇技淫巧,以及对C和C++语言的详细掌握,那是类库编写者的工作
我们应该关注业务逻辑,主要的工具还是C++基础和面向对象的知识,以及标准库
*//*
函数模板和类模板成员函数的定义应放在头文件中
*//*
函数模板 或 模板函数
*/
template <typename T> // typename 可以用 class 替换
bool less(const T& l, const T& r)
{return l < r;
}
void less_demo()
{less(1, 2); // T 为 intless(1.0, 2.0); // T 为 doubleless<std::string>("abc", "abd"); // 强制 T 为 std::string
}
/*
这个例子充当排序的可调用对象
其实标准库有实现好的 std::less 在头文件 <functional>
只不过它是用类重载operator()实现的
*/
void i_don_t_want_to_reimplement_less()
{int a[10]{ 0, 9, 8, 7, 6, 5, 4, 3, 2, 1 };// std::begin(a) == a// std::end(a) == a + 10// std::less<int>() 构造一个右值,它是一个可调用对象std::sort(std::begin(a), std::end(a), std::less<int>());
}
// 以上的 std::end 是怎么实现的呢,它怎么知道要 + 10,问题是如何获取数组的尺寸
void array_type()
{int a[10]{};// 对于强类型的C++而言,数组的尺寸也是类型的一部分using T = decltype(a); // T 是 int[10];// 如何声明数组的引用,不知道怎么写就借助 auto 的力量auto& ra = a; // ra 的类型为 int (&)[10],即绑定到数组的引用
}
// 打印数组的尺寸,这里体现了模板在编译时的强大
template <typename T, unsigned int ARRAY_SIZE> // T 称为类型参数,ARRAY_SIZE称为非类型参数
void print_array_size(T (&)[ARRAY_SIZE]) // 用引用绑定到数组,尺寸使用非类型参数
{std::cout << "The size of array is: " << ARRAY_SIZE << std::endl;
}int main()
{int a[10];print_array_size(a);// 抛开模板,怎么做?int array_size1 = sizeof(a) / sizeof(*a);// 或int array_size2 = sizeof(a) / sizeof(a[0]);
}/*
类模板 或 模板类
*/
template <class T, unsigned int SIZE>
class MyArray
{
};
void myarray_demo()
{MyArray<int, 10> array;
}
/*
标准库实现了std::array
*/
void stdarray_demo()
{std::array<int, 10> array;
}/*
using 的用法
1. 引用命名空间里的东西 比如 using namespace std;
2. 声明类型别名,比如 using T = decltype(main);
*/

Day8-4 C++语法知识复习(2025.03.31)


1. 运算符重载回顾

常见重载场景

运算符典型应用返回值建议
+ - * /数学运算值类型
=赋值操作左值引用
<< >>流操作流引用
()函数对象任意
[]容器访问引用

2.现代枚举系统

传统枚举问题

enum Color { Red, Green };  // 污染全局命名空间
int Red = 5;  // 冲突!

枚举类优势

enum class Weekday : uint8_t { Monday = 1,Tuesday  // 自动递增
};void use_enum() {Weekday day = Weekday::Monday;uint8_t value = static_cast<uint8_t>(day);  // 需要显式转换
}

3. 断言机制详解

断言类型对比

类型检查时机头文件示例
assert运行时<cassert>assert(ptr != nullptr)
static_assert编译时语言内置static_assert(sizeof(int)==4)

最佳实践

constexpr int BUFFER_SIZE = 1024;
static_assert(BUFFER_SIZE > 0, "Buffer size must be positive");void safe_operation() {int* ptr = get_pointer();assert(ptr && "Pointer cannot be null");
}

4. 数值字面量增强

现代字面量语法

int decimal = 1'000'000;    // 千分位分隔
int hex = 0xFF'FF'FF;       // 颜色值
int binary = 0b1010'0101;   // 二进制
double sci = 1.23e-10;      // 科学计数法

5. 字符系统

字符类型对比

类型大小编码字符串类型输出流
char1字节ASCIIstd::stringstd::cout
wchar_t2/4字节Unicodestd::wstringstd::wcout
char16_t2字节UTF-16std::u16string-
char32_t4字节UTF-32std::u32string-

6.附录:模板元编程入门

// 编译期计算斐波那契数列
template<int N>
struct Fibonacci {static const int value = Fibonacci<N-1>::value + Fibonacci<N-2>::value;
};template<>
struct Fibonacci<0> { static const int value = 0; };template<>
struct Fibonacci<1> { static const int value = 1; };static_assert(Fibonacci<5>::value == 5, "Compile-time check");

7. 完整测试代码

#include <cassert>
#include <type_traits>/*
查漏补缺
*//*
运算符重载存在于C++的每个角落,要习惯1. + - * / 数值运算符,服务于数学类型2. = 赋值运算符,比如拷贝赋值,移动赋值,或者其他类型向该类型赋值3. << >> 流输出和流输入,多用于打印,或转为字符串4. () 可调用对象,供容器、算法、线程等库使用5. [] 下标运算符,供容器使用,比如std::map(有序树),std::unordered_map(哈希表)有重载,用于访问键值对6. -> ++ -- 实现行为像指针的类,比如智能指针,迭代器7. new delete 自己实现内存分配和释放,除非你是内存管理专家8*. operator"" 可以为数学值添加“单位” https://zhuanlan.zhihu.com/p/111369693
*//*
数值类型补充C++14起,可以使用二进制数值字面值 以0b打头。
常用的还有十六进制,以0x打头。
*/
int bin_a = 0b0101;
int hex_a = 0xFF;
/*
数值字面值可以添加 ' 以提高可读性
*/
int bin_b = 0b0101'0101;
int b = 12'3456'7890;/*
枚举
enum关键字,本质定义了一个命名的常量
也称为 弱枚举,
*/
enum Color // 默认用 int 实现,可以修改
{Red, // 默认从 0 开始,可以修改Blue, // 自动从上一个累加 1,如果上一个是 0,该值为 1
};
/*
枚举类
enum class关键字,定义了有范围的枚举,本质加了命名空间,以及增强了类型(不可以隐式转换为实现类型)
也称为 强枚举,范围枚举
*/
enum class Weekend : unsigned short // 修改默认实现类型
{Saturday = 6,Sunday, // 7
};
// 编译器实际上把该强枚举翻译为命名空间里的常量
namespace _Weekend
{const unsigned short Saturday = 6;const unsigned short Sunday = 7;
}
void enum_demo()
{Color r = Color::Red;// underlying_type_t 可以查看枚举和枚举类的实现类型using Tc = std::underlying_type_t<Color>; // intint ir = r; // 隐式转为 整型Weekend w = Weekend::Saturday;using Tw = std::underlying_type_t<Weekend>; // unsigned shortint iw = (int)w; // 无法隐式转换,需要显式转换// 枚举多见于 if else / switch case 做匹配switch (w){case Weekend::Saturday:// ...break;case Weekend::Sunday:// ...break;}
}/*
窄字符与宽字符
窄字符,ANSI编码,即普通 ASCII 字符,用 char 表示,对应的C++字符串为 std::string,对应的标准输出为 std::cout
宽字符,Unicode编码,用 wchar_t 表示,对应的C++字符串为 std::wstring,对应的标准输出为 std::wcout
*//*
断言 用来写测试
包含头文件 <cassert>
*/
void assert_test()
{// 运行时断言int a = 1; // 变量,运行时赋值assert(a == 1);// 变量不可以做栈数组的尺寸,但可以做堆数组的// 编译时断言const int b = 1; // 使用 const 声明常量,编译时赋值static_assert(b == 1);int array1[b]; // 常量才能做栈数组的尺寸constexpr int c = 1; // 使用 constexpr 声明编译时常量(比const更强的编译时要求),编译时赋值static_assert(c == 1);int array2[c]; // 编译时常量更有资格做栈数组的尺寸
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词