网站开发容易找工作吗设计学习
- 作者: 五速梦信息网
- 时间: 2026年03月21日 07:36
当前位置: 首页 > news >正文
网站开发容易找工作吗,设计学习,网站建设客户需求分析调查表,网站建设怎么进后台本专栏记录C学习过程包括C基础以及数据结构和算法#xff0c;其中第一部分计划时间一个月#xff0c;主要跟着黑马视频教程#xff0c;学习路线如下#xff0c;不定时更新#xff0c;欢迎关注。 当前章节处于#xff1a; ———第1阶段-C基础入门 ———第2阶段实战… 本专栏记录C学习过程包括C基础以及数据结构和算法其中第一部分计划时间一个月主要跟着黑马视频教程学习路线如下不定时更新欢迎关注。 当前章节处于 ———第1阶段-C基础入门 ———第2阶段实战-通讯录管理系统 ———第3阶段-C核心编程 ———第4阶段实战-基于多态的企业职工系统 第5阶段-C提高编程 ———第6阶段实战-基于STL泛化编程的演讲比赛 ———第7阶段-C实战项目机房预约管理系统 文章目录 一、概念二、函数模板2.1 基本语法2.2 注意事项2.3 普通函数和模板函数的区别2.4 普通函数和函数模板调用规则2.5 模板的局限性 三、类模板3.1 基本语法3.2 类模板中成员函数创建时机3.3 类模板对象做函数参数3.4 类模板与继承3.5 类模板成员函数类外实现3.6 类模板分文件编写3.7 类模板和友元 一、概念 模板就是建立通用的模具大大提高复用性。模板不可以直接使用只是一个框架并且模板的通用并不是万能的。使用模板的目的是提高复用性将类型参数化。 二、函数模板 2.1 基本语法 template 函数声明或定义 template声明创建模板typename:表明其后面的符号是一种数据类型可以用class代替T通用的数据类型名称可以替换通常为大写字母可以定义多个 #include iostream using namespace std;// 定义一个交换的函数模板 template typename T void Myswap(T a, T b) {T temp a;a b;b temp; }void test() {int a 10;int b 20;char c c;char d d;// 1. 自动推导型Myswap(a, b);cout a a endl;cout b b endl;// 2. 显示推导型Myswapchar(c, d);cout c c endl;cout d d endl;}int main() {test();system(pause);return 0;}a20 b10 cd dc 请按任意键继续…2.2 注意事项 自动类型推导必须推导出一致的数据类型才可以使用模板必须要确定出T的数据类型才可以使用 第一个好理解比如上面的Myswap如果传入的两个实参类型不一致时则会导致推导出来的T的类型不一致则无法使用。下面对于第二点进行代码讲解 #include iostream using namespace std;// 定义模板 template class T void func() {cout 调用函数模板 endl; }void test() {// func(); // 错误funcint(); // 正确 }int main() {test();system(pause);return 0;}调用函数模板 请按任意键继续…实战案例 利用函数模板封装一个排序的函数可以对不同数据类型数组进行排序排序规则从大到小排序算法为选择排序分别利用char数组和int数组进行排序 #include iostream using namespace std;// 排序函数模板 templateclass T void func(T arr[],int length) {// 选择排序for (int i 0; i length; i) {int max i; // 认为当前的是最大值for (int j i1; j length; j) {if (arr[max] arr[j]) {max j;}}// 调换两个值T temp arr[i];arr[i] arr[max];arr[max] temp;} }// 打印函数模板 template class T void printArr(T arr[],int length) {for (int i 0; i length; i) {cout arr[i] ;}cout endl; }// 测试整型 void test01() {int arr[10] { 1,4,3,2,6,7,5,9,8,0 };func(arr, 10);printArr(arr, 10); } void test02() {char arr[] acbdfeg;int length sizeof(arr) / sizeof(arr[0]);func(arr,length);printArr(arr, length); } int main() {test01();test02();system(pause);return 0;}9 8 7 6 5 4 3 2 1 0 g f e d c b a 请按任意键继续…2.3 普通函数和模板函数的区别 普通函数调用时可以发生自动类型转化隐式类型转化函数模板调用时如果利用自动类型推导不会发生隐式类型转换如果利用显示指定类型的方式可以发生隐式类型转化 #include iostream using namespace std;// 定义一个函数模板 templateclass T T func1(T a, T b) {cout 调用的是函数模板 endl;return a b; }// 定义一个普通函数 int func2(int a,int b) {cout 调用的是普通函数 endl;return a b; }// 测试案例 void test() {int a 10;int b 20;char c c;cout func1(a, b) endl;cout func2(a, c) endl;//cout func1(a, c) endl;// 报错cout func1int(a, c) endl;// 不报错 } int main() {test();system(pause);return 0;}调用的是函数模板 30 调用的是普通函数 109 调用的是函数模板 109 请按任意键继续…2.4 普通函数和函数模板调用规则 如果函数模板和普通函数都可以实现优先调用普通函数可以通过空模板参数列表来强制调用函数模板函数模板也可以发生重载如果函数模板可以更好的匹配优先调用函数模板 下面通过具体代码进行逐个讲解 #include iostream using namespace std; // 定义普通函数 void MyPrint(int a,int b) {cout 调用的是普通函数 endl; }// 定义模板函数 templateclass T void MyPrint(T a, T b) {cout 调用的是模板函数 endl; } // 重载模板函数 templatetypename T void MyPrint(T a, T b, T c) {cout 调用重载的模板函数 endl; }int main() {// 1. 如果函数模板和普通函数都可以实现优先调用普通函数int a 10; int b 20;MyPrint(a, b);// 2.可以通过空模板参数列表来强制调用函数模板MyPrint(a, b);// 3.函数模板也可以发生重载MyPrint(a, b, 30);// 4.如果函数模板可以产生更好的匹配,优先调用函数模板char c1 a;char c2 b;MyPrint(c1, c2);system(pause);return 0;}调用的是普通函数 调用的是模板函数 调用重载的模板函数 调用的是模板函数 请按任意键继续…总结如果提供了函数模板最好就不要再提供对应的普通函数否则容易出现二义性。 2.5 模板的局限性 如果T的数据类型传入的是像Person这样的自定义数据类型也无法正常进行比较运算C为了解决这种问题提供模板的重载为这些特定类型提供具体化模板。 #include iostream using namespace std; class Person { public:Person(string name,int age) {m_Name name;m_Age age;}string m_Name;int m_Age; }; // 普通函数模板 templateclass T bool myCompare(T a, T b) {return a b; } // 具体化 优先于常规模板 template bool myCompare(Person p1, Person p2) {if (p1.m_Name p2.m_Name p1.m_Age p2.m_Age){return true;}else{return false;} }void test() {Person p1(Tom, 10);Person p2(Tom, 10);cout myCompare(p1, p2) endl; } int main() {test();system(pause);return 0;}1 请按任意键继续…利用具体化的模板可以解决自定义类型的通用化学习模板并不是为了写模板而是再STL中能够运用系统提供的模板。 三、类模板 类似于函数模板类有也对应的类模板类模板的作用是建立一个通用类类中的成员数据类型可以不具体制定用一个虚拟的类型来代表语法为 templatetypename T 类 template — 声明创建模板typename — 表面其后面的符号是一种数据类型可以用class代替T — 通用的数据类型名称可以替换通常为大写字母 3.1 基本语法 #include iostream using namespace std;// 定义一个交换的函数模板 template typename T void Myswap(T a, T b) {T temp a;a b;b temp; }void test() {int a 10;int b 20;char c c;char d d;// 1. 自动推导型Myswap(a, b);cout a a endl;cout b b endl;// 2. 显示推导型Myswapchar(c, d);cout c c endl;cout d d endl;}int main() {test();system(pause);return 0;}姓名孙悟空 年龄999 姓名猪八戒 年龄888 请按任意键继续…3.2 类模板中成员函数创建时机 类模板中成员函数和普通类中成员函数创建时机是有区别的 普通类中的成员函数一开始就可以创建类模板中的成员函数再调用时才创建 #include iostream using namespace std; class Person1 { public:void showPerson1(){cout Person1 show endl;} };class Person2 { public:void showPerson2(){cout Person2 show endl;} }; // 定义类模板 templateclass T class MyClass { public:T obj;//类模板中的成员函数并不是一开始就创建的而是在模板调用时再生成void fun1() { obj.showPerson1(); }void fun2() { obj.showPerson2(); }}; void test01() {MyClassPerson1 m;m.fun1();//m.fun2();//编译会出错说明函数调用才会去创建成员函数 } int main() {test01();system(pause);return 0;}Person1 show 请按任意键继续…3.3 类模板对象做函数参数 类模板实例化出的对象向函数传参的方式 一共有三种传入方式 指定传入的形式直接显示对象的数据类型这是用的最多的一种方式参数模板化将对象中的参数变为模板进行传递整个类模板化将这个对象类型模板化进行传递 下面用代码进行讲解 #include iostream using namespace std; // 创建一个类模板 templateclass NameType, class AgeType int // 默认参数为int class Person { public:Person(NameType name, AgeType age){this-mName name;this-mAge age;}void showPerson(){cout name: this-mName age: this-mAge endl;} public:NameType mName;AgeType mAge; }; //1、指定传入的类型最常用的一种方式 void printPerson1(Personstring, int p) {p.showPerson(); } void test01() {Person string, int p(孙悟空, 100);printPerson1(p); }//2、参数模板化 template class T1, class T2 void printPerson2(PersonT1, T2 p) {p.showPerson();cout T1的类型为 typeid(T1).name() endl;cout T2的类型为 typeid(T2).name() endl; } void test02() {Person string, int p(猪八戒, 90);printPerson2(p); }//3、整个类模板化 templateclass T void printPerson3(T p) {cout T的类型为 typeid(T).name() endl;p.showPerson();} void test03() {Person string, int p(唐僧, 30);printPerson3(p); }int main() {test01();test02();test03();system(pause);return 0; } int main() {system(pause);return 0;}name: 孙悟空 age: 100 name: 猪八戒 age: 90 T1的类型为 class std::basic_stringchar,struct std::char_traitschar,class std::allocatorchar T2的类型为 int T的类型为 class Personclass std::basic_stringchar,struct std::char_traitschar,class std::allocatorchar ,int name: 唐僧 age: 30 请按任意键继续…3.4 类模板与继承 当类模板碰到继承时需要注意一下几点 当子类继承的父类是一个类模板时子类在声明的时候要制定出父类中T的类型如果不指定编译器无法给子类分配内存如果想灵活指定出父类中T的类型子类也需变成类模板 #include iostream // 父类类模板 using namespace std; templateclass T class Base {T m; };// 子类继承父类 // class Son :public Base {}; // 错误必须要确定父类中的T class Son :public Baseint {}; void test01() {Son c;// 实例化对象 } templateclass T2 class Son2 :public BaseT2 { public:Son2(){cout typeid(T2).name() endl;} };void test02() {Son2char child1; } int main() {test01();test02();system(pause);return 0;}char 请按任意键继续…3.5 类模板成员函数类外实现 #include iostream using namespace std;templateclass NameType, class AgeType int // 默认参数为int class Person { public:Person(NameType name, AgeType age);void showPerson(); public:NameType mName;AgeType mAge; }; // 构造函数 类外实现 templateclass NameType, class AgeType PersonNameType, AgeType::Person(NameType name, AgeType age) {this-mName name;this-mAge age; } // 成员函数类外实现 templateclass NameType, class AgeType void PersonNameType, AgeType::showPerson() {cout name: this-mName age: this-mAge endl; }int main() {Personstring, int p(张三, 13);p.showPerson();system(pause);return 0;}name: 张三 age: 13 请按任意键继续…3.6 类模板分文件编写 由于类模板中成员函数创建时机是在调用阶段导致分文件编写时连接不到有两种解决方案 直接包含cpp源文件将声明和实现写到同一个文件中并更改后缀名为.hpp 更常用 Person.hpp #pragma once #include iostream using namespace std;templateclass NameType, class AgeType int // 默认参数为int class Person { public:Person(NameType name, AgeType age);void showPerson(); public:NameType mName;AgeType mAge; }; // 构造函数 类外实现 templateclass NameType, class AgeType PersonNameType, AgeType::Person(NameType name, AgeType age) {this-mName name;this-mAge age; } // 成员函数类外实现 templateclass NameType, class AgeType void PersonNameType, AgeType::showPerson() {cout name: this-mName age: this-mAge endl; }类模板分文件编写.cpp #include iostream using namespace std;#include Person.hppint main() {Personstring, int p(张三, 13);p.showPerson();system(pause);return 0;}name: 张三 age: 13 请按任意键继续…3.7 类模板和友元 #include iostream using namespace std; template class T1,class T2 class Person;// 2. 全局函数类外实现 template class T1, class T2 void showPerson(PersonT1, T2 p) {cout 姓名 p.m_Name 年龄 p.m_Age endl; }template class T1, class T2 class Person {// 1. 全局函数类内实现// 加上friend变为全局函数如果不加的话就是成员函数//friend void showPerson(PersonT1,T2 p) {// cout 姓名 p.m_Name 年龄 p.m_Age endl;//}// 如果全局函数是类外实现需要让编译器提前知道这个函数存在friend void showPerson(PersonT1, T2 p); public:Person(T1 name, T2 age) {this-m_Name name;this-m_Age age;} private:T1 m_Name;T2 m_Age; };int main() {Personstring, int p(Tom, 12);showPerson(p);system(pause);return 0;}姓名Tom 年龄12 请按任意键继续…实战案例 实现一个通用的数组类 可以对内置数据类型以及自定义数据类型的数据进行存储将数组中的数据存储到堆区构造函数中可以川入数组的容量提供对应的拷贝构造函数以及operator防止浅拷贝问题提供尾插法和尾删法对数组中的数据进行增加和删除可以通过下标的方式访问数组中的元素可以获取数组中当前元素个数和数组的容量 main.cpp #include iostream using namespace std; #include MyArray.hpp class Person { public:Person() {}Person(string name, int age) {m_name name;m_age age;}string getName() {return m_name;}int getAge() {return m_age;} private:string m_name;int m_age0; };void showPerson(MyarrayPerson array,int num) {for (int i 0; i num; i) {cout 姓名 array[i].getName() 年龄array[i].getAge()endl;} } void showInt(Myarrayint arr, int num) {for (int i 0; i num; i) {cout arr[i] ;}cout endl; }void test() {Myarrayint arr(10);for (int i 0; i 10; i) {arr.insert_Back(i);}showInt(arr, 10);//Myarrayint arr2(arr);//Myarrayint arr3(20);//arr3 arr;//cout arr3的容量为 arr3.get_Mcap() endl;MyarrayPerson PersonArr(2);Person p1(张三, 12);Person p2(李四, 21);PersonArr.insert_Back(p1);PersonArr.insert_Back(p2);showPerson(PersonArr,2); } int main() {test();system(pause);return 0;}MyArray.hpp #pragma once #include iostream using namespace std;template class T class Myarray { public:// 有参构造Myarray(int cap) {cout 调用有参构造函数 endl;//cout hello endl;this-m_cap cap;this-pArray new T[this-m_cap]; // 在堆区开辟this-size 0;}// 拷贝构造Myarray(Myarray arr) {//cout 调用拷贝构造函数 endl;this-size arr.size;this-m_cap arr.m_cap;this-pArray new T[arr.m_cap];// 将arr中的数据拿过来for (int i 0; i arr.size; i) {this-pArray[i] arr.pArray[i];}}// 析构函数~Myarray() {if (this-pArray! NULL) {cout 调用析构函数 endl;this-m_cap 0;this-size 0;// pArray是个数组 删除时要注意格式delete[] pArray;pArray NULL;//cout 删除完成 endl;}}// 重载操作运算符Myarray operator(const Myarray arr) {//cout 调用operator函数 endl;// 先判断原来栈区是否有数据if (this-pArray ! NULL) {delete[] pArray;pArray NULL;this-m_cap 0;this-size 0;}this-m_cap arr.m_cap;this-size arr.size;this-pArray new T[arr.m_cap];return *this;}// 重载[]操作运算符T operator {return pArray[index];}// 获取数组容量int get_Mcap() {return this-m_cap;}// 获取数组大小int get_Size() {return this-size;}// 获取// 尾插法void insert_Back(T value) {// 判断还有无空间if (this-size this-m_cap) {cout 达到插入上限 endl;return ;}this-pArray[this-size] value;this-size;//return this;}// 尾删法void pop_Back() {// 判断是否为0if (this-size 0) {cout 已达删除上限 endl;return;}this-size–;}// 通过下标方式访问元素T get_index(int index) {if (index0 || indexthis.size) {cout 索引有无 endl;return;}return this-pArray[index];} private:T pArray; // 头指针int m_cap; // 容量int size; // 大小 }; 调用有参构造函数 0 1 2 3 4 5 6 7 8 9 调用析构函数 调用有参构造函数 姓名张三 年龄12 姓名李四 年龄21 调用析构函数 调用析构函数 调用析构函数 请按任意键继续…
- 上一篇: 网站开发任务书物流网站的建设论文
- 下一篇: 网站开发如何避免浏览器缓存的影响肇庆seo排名
相关文章
-
网站开发任务书物流网站的建设论文
网站开发任务书物流网站的建设论文
- 技术栈
- 2026年03月21日
-
网站开发任务书wordpress git themes
网站开发任务书wordpress git themes
- 技术栈
- 2026年03月21日
-
网站开发人员招聘做互联网平台要多少钱
网站开发人员招聘做互联网平台要多少钱
- 技术栈
- 2026年03月21日
-
网站开发如何避免浏览器缓存的影响肇庆seo排名
网站开发如何避免浏览器缓存的影响肇庆seo排名
- 技术栈
- 2026年03月21日
-
网站开发入股合作分配比例wordpress 热门关键字
网站开发入股合作分配比例wordpress 热门关键字
- 技术栈
- 2026年03月21日
-
网站开发入门看什么动物大联盟微信小程序入口
网站开发入门看什么动物大联盟微信小程序入口
- 技术栈
- 2026年03月21日






