类模板

一、类模板写法 1. 声明和定义写在一起 template<class T> class Person{ public: Person(T age){ this->m_age = age; } void Show(){ cout << this->m_age << endl; } private: T m_age; }; int main() { Person<int> p(20); p.Show(); cout << p << endl; printP(p); return 0; } 2. 声明和定义分开写,但在同一文件中 template<class T> class Person{ public: Person(T age); void Show(); private: T m_age; }; template<class T> Person<T>::Person(T age){ this->m_age = age; } template<class T> void Person<T>::Show(){ cout << this->m_age << endl; } int main() { Person<int> p(20); p....

January 12, 2022 · 2 min · Rick Cui

编译过程

各个 .cpp 文件是独立编译的,如果有其它的类和函数会先在本 .o 文件中生成符号,由最后的链接器去其它 .o 文件找具体的函数定义 .c .cpp 文件经过 预编译器拷贝头文件、宏展开 生成 .i 文件(文本文件) g++ -E main.cpp -o main.i .i 文件经过 编译器 生成汇编程序 .s(文本文件) g++ -S main.i -o main.s .s 文件经过 汇编器 生成可定位目标文件 .o (二进制) Windows: g++ -c main.s -o main.obj Linux: g++ -c main.s -o main.o .o 文件经过 链接器 生成可执行目标文件 .exe .dll g++ main.s -o main

January 12, 2022 · 1 min · Rick Cui

函数模板

函数模板必须严格类型匹配,普通函数则可以进行数据类型隐式转换 对于内置数据类型,函数模板可进行推导,自定义类型不可以 函数模板可被重载 C++ 编译器优先考虑普通函数 可以通过空模板实参列表的语法限定编译器只能通过模板匹配 如果函数模板可以产生一个更好的匹配,就选择模板 编译器根据函数模板调用情况,从函数模板和具体类型产生不同的函数 编译器会对函数模板进行两次编译 在声明的地方对模板代码本身进行编译; 在调用的地方对参数替换后的代码进行编译 template<class T> T MyAdd(T a, T b){ return a + b; } // 函数一 int MyAdd(int a, int b){ return a + b; } // 函数二 int MyAdd(int a, char c){ return a + c; } int main() { cout << MyAdd(1, 2) << endl; // 优先调用普通函数 cout << MyAdd<>(1, 2) << endl; // 强制调用模板函数 cout << MyAdd(1....

January 11, 2022 · 1 min · Rick Cui

C 语言面向接口编程

通过函数指针实现多态,注册回调函数的方式 void printAllArray(void* arr, int eleSize, int len, void(*myPrint)(void*)){ char* arrStart = (char*)arr; for(int i = 0; i < len; ++i){ char* eleStart = arrStart + i * eleSize; myPrint(eleStart); } printf("\n"); } void printInt(void* data){ int* ele = (int*)data; printf("%d ", *ele); } struct Person{ char name[64]; int age; }; void printPerson(void* data){ struct Person* ele = (struct Person*)data; printf("Name: %s, Age: %d \n", ele->name, ele->age); } int main() { int arr[] = {1, 2, 3, 4, 5}; printAllArray(arr, sizeof(int), 5, printInt); struct Person personArr[] = { {"aaa", 20}, {"bbb", 30}, {"ccc", 40}, {"ddd", 50}, {"eee", 60}, }; printAllArray(personArr, sizeof(struct Person), 5, printPerson); return 0; } 输出:...

January 10, 2022 · 1 min · Rick Cui

面向抽象类编程

三层架构:业务逻辑层、抽象层、实现层 原则:依赖倒转 案例一:动物园 设计实现: 抽象层:Animal 提供接口 voice 实现层:Dog、Cat 分别实现 voice ,发出不同的声音 业务层:main 函数调用,只通过 Animal 的指针统一实现业务 案例二:编写一个 C++ 程序, 计算程序员( programmer )工资 要求能计算出初级程序员( junior_programmer ) 中级程序员 ( mid_programmer )高级程序员( adv_programmer )的工资 要求利用抽象类统一界面,方便程序的扩展,比如:新增,计算架构师( architect ) 的工资 设计实现: 抽象层:Programmer 提供计算工资的接口 实现层:JuniorProgrammer、MidProgrammer、AdvProgrammer 分别对计算工资接口进行实现 业务层:通过 Programmer 类统一管理,实现业务逻辑,同时业务的可扩展性更强,如新增架构师类型 案例三:电脑组装,面向抽象层编程 组装电脑有 3 个抽象类,抽象的 cpu,抽象的显卡,抽象的内存。 现在要求组装两台电脑,一台是 Intel 的 CPU,Intel 的显卡和 Intel 的内存。另一台是 Intel 的 CPU、Nvidia 的显卡和 Kingston 的内存条。 针对抽象层编程。 设计实现:...

January 9, 2022 · 1 min · Rick Cui