建设视频网站要求wordpress 文档模板

张小明 2026/1/9 21:49:06
建设视频网站要求,wordpress 文档模板,慧拓客电销系统,绍兴高端网站开发目录 9.1 类模板声明9.2 实现类模板9.3 类模板的怪癖9.3.1 **typename**​**vs.**​**class**9.3.2 默认参数9.3.3 无类型参数 9.4 const 正确性9.4.1 const方法9.4.2 const接口9.4.3 const重载9.4.4 const\_cast9.4.5 mutable 编写一个int_vector: class int_vect…目录9.1 类模板声明9.2 实现类模板9.3 类模板的怪癖9.3.1 **typename**​**vs.**​**class**9.3.2 默认参数9.3.3 无类型参数9.4 const 正确性9.4.1 const方法9.4.2 const接口9.4.3 const重载9.4.4 const\_cast9.4.5 mutable编写一个int_vector:classint_vector{public:voidpush_back(inti);size_tsize()const;intoperator[](size_t index)const;/* Other methods and implementation hidden */};double_vector将包含与int_vector和string_vector非常相似的逻辑唯一显著的区别在于数据类型的变化。这不仅使得编写工作繁琐而且如果类接口需要更改维护起来也很困难。模板为这个问题提供了一种解决方案。我们将使用一个或多个模板参数为我们的类声明一个模板这些参数在我们使用该模板时会被替换为特定的类型。模板保持逻辑改变类型。9.1 类模板声明我们可以将我们的int_vector、double_vector、string_vector合并成一个单一的vector类模板如下所示templatetypenameT// vector 是一个模板它接收一个类型 T 的名称。classvector{public:voidpush_back(constTv);// vector被实例化时T被替换size_tsize()const;Toperator[](size_t index)const;/* Other methods and implementation hidden */};这个模板看起来几乎和普通类完全一样只是我们在它前面加上了template。这种语法引入了一个单一的模板参数T它代表一个类型名称。然后当我们编写vectorint v编译器会通过将每个T的实例都文本替换为int来实例化该模板从而生成一个类声明。对于给定的模板参数配置实例化只会发生一次 —— 如果我们在同一个文件中再次使用vector则会重用已实例化的模板。如果我们编写vectorint v1;vectordouble v2;vectorstd::string v3;编译器会生成三个不同的模板形成三个完全不同类型。它们的​运行时和编译时类型完全不同​。Java不是Java中ArrayListint和ArrayListdouble分享​相同的运行时类型​模板VS类型最终结果与我们手动写出一个int_vector、double_vector和string_vector的结果相同。优点如下编译器自动生成这些类的能力克服了前面提到的手动编写类的局限性。消除了冗余。如果模板发生更改编译器会在编译时获取最新的更改。核心思想模板用来自动生成代码。注意​模板类并非类​。模板只有在填充了所有模板参数后才会成为类。从表示法上来说vector 是一个类模板而 vector是一个实际的类。实例化的一个结果是vector和 vector是本质上不同的类型。尽管它们是从同一个模板实例化而来但它们的区别就如同我们手动编写的 int_vector 和 double_vector 之间的区别一样。例如一个期望接收 vector的函数无法接受 vector。要编写一个能够接受任何vector的函数我们需要将该函数本身定义为模板。这一点将在下一章中讨论。实例化的另一个后果是我们可以预料到使用模板的程序会更大编译速度也更慢。程序会更大是因为会生成更多冗余的代码并包含在最终的可执行文件中就像一个声明并使用int_vector、double_vector和string_vector的程序会比只包含int_vector的程序更大。编译时间会更长因为编译器必须多进行一次传递来实例化模板。9.2 实现类模板上面的vector模板声明了三个方法push_back、size和operator[]。我们要在哪里定义这些方法呢#includevector.htemplatetypenameTvoidvectorT::push_back(constTv){/* ... */}// 注意涂黄的部分T不能省略templatetypenameTsize_tvectorT::size()const{/* ... */}templatetypenameTTvectorT::operator[](size_t index)const{/* ... */}如前所述将定义放入像这样的.cpp文件中可以缩短编译时间。当另一个文件想要使用vector时只需包含vector.h即可 —— 无需再编译vector.cpp。这被称为分离编译。但遗憾的是​模板无法进行分离编译我们无法轻松地将其代码拆分到.h文件和.cpp文件中。因此编译器在任何包含模板的地方都必须看到整个模板。换句话说包含vector.h也应该包含它的定义。因此类模板通常以仅头文件库的形式分发它们将模板的实现完全放在一个文件中。以上面的vector模板为例我们可以通过以下三种方式来实现一个模板1、在.h文件中内联编写定义。templatetypenameTclassvector{public:voidpush_back(constTv){/* ... */}size_tsize()const{/* ... */}Toperator[](size_t index)const{/* ... */}/* Other methods and implementation hidden */};2、在声明下方编写定义。templatetypenameTclassvector{public:voidpush_back(constTv);size_tsize()const;Toperator[](size_t index)const;/* Other methods and implementation hidden */};templatetypenameTvoidvectorT::push_back(constTv){/* ... */}templatetypenameTsize_tvectorT::size()const{/* ... */}templatetypenameTTvectorT::operator[](size_t index)const{/* ... */}3、从.h文件中包含一个.cpp文件。这与您通常会做的相反// vector.htemplatetypenameTclassvector{public:voidpush_back(constTv);size_tsize()const;Toperator[](size_t index)const;/* Other methods and implementation hidden */};#includevector.cpp// vector.cpptemplatetypenameTvoidvectorT::push_back(constTv){/* ... */}templatetypenameTsize_tvectorT::size()const{/* ... */}templatetypenameTTvectorT::operator[](size_t index)const{/* ... */}无模板的类模板类这些方法存在一个问题那就是它们可能会在不经意间增加编译时间因为每个包含vector.h的文件最终都会单独编译相同的定义。但在实际应用中这通常不是什么问题而且大多数模板库例如 g 编译器对标准模板库头文件如vector和map的实现都采用仅头文件库的形式。例如vector的 g 源代码可以在一个仅含头文件的库中找到该库名为 bits/stl_vector.h其中包含实际的 vector 模板声明。还有第四种不太常用的方法可以解决这个问题同时仍能享受分离编译的好处。我们可以像处理类时通常做的那样将.h文件和.cpp文件分开然后​在.cpp文件中提前显式实例化模板:vector.cpp文件#includevector.h/* Definitions of the vector methods */// Explicit instantiation:templateclassvectorint;templateclassvectordouble;templateclassvectorstd::string;模板类语法会显式实例化模板这样包含vector.h的另一个文件就能创建vector的int、double或std::string类型并使用其方法。例如尝试对vector或任何其他未实例化的类型执行相同操作将会导致编译器错误。这样做的好处是缩短编译时间并减小编译后程序的大小但代价是缺乏一定的灵活性 —— 我们必须提前在.cpp文件中指定模板实例化以编译相关的定义。9.3 类模板的怪癖9.3.1typename​vs.​class在阅读模板代码时你可能会看到用class来代替typename。templatetypenameTclassvector{};templateclassTclassvector{};这两种形式是完全相同的并且可以互换使用。它们之间的区别是 C 历史遗留下来的 —— 最初class被用来指代任何类型的名称后来为了可读性这一用法扩展到了typename。9.3.2 默认参数可以为模板参数指定一个默认参数。如果未指定该参数则将使用默认参数类型。例如在std::vector以及许多其他容器数据类型的定义中可以提供一个分配器类型来改变容器中元素的分配方式。下面的示例展示了std::vector如何使用Allocator模板参数为10个类型为T的元素分配空间。templatetypenameT,typenameAllocatorstd::allocatorTclassstd::vector{vector():_alloc(),_data(_alloc.allocate(10)){}~vector(){_alloc.deallocate(_data,_size);}private:Allocator _alloc;T*_data;size_t _size0;size_t _capacity10;};如果未指定Allocator则会使用std::allocator它通过new来分配对象并通过delete来释放对象。就std::vector而言这使得该数据类型的用户能够指定元素数据的分配位置和分配方式。9.3.3 无类型参数与其他支持泛型编程的语言不同模板参数并没有被限制为必须引用特定类型。例如它们可以是int、size_t、float或任何其他编译时常量。比如考虑std::arraytemplatetypenameT,size_t Nstructstd::array{/* Other public methods and functionality */private:T[N]_data;};在这种情况下std::array会在其内存布局中为N个类型为T的元素预留空间这有可能带来性能优势因为不需要通过堆分配来为这N个元素预留空间如下例所示std::vectorintvec{1,2,3,4,5};std::arrayint,5fiveArray;std::arrayint,10tenArray;请注意对于std::array其_data字段直接嵌入到栈上对象的内存布局中。还要注意与vector不同array的大小在编译时是固定的并且更改N的值会产生不同的类型将std::arrayint, 5赋值给std::arrayint, 10 是无效的原因与将vectorint赋值给vectordouble相同。9.4 const 正确性前面文章提到过的const如果一个变量是const其引用也得是const见2.4范围for循环的const auto见4.2const与指针见5.2.1const迭代器见6.4.19.4.1 const方法templatetypenameT// vector 是一个模板它接收一个类型 T 的名称。classVector{public:size_tsize();boolempty();Toperator[](size_t index);Tat(size_t index);voidpush_back(constTelem);};错误voidprintVec(constVectorintv){for(size_t i0;iv.size();i){std::coutv.at(i) ;}std::coutstd::endl;}// Compiler: “No such method size!”为什么通过将 v 声明为 const我们保证不会修改 v。编译器无法确定像 size 和 at 这样的方法是否会修改 v。记住成员函数可以访问成员变量。怎么修复/////////////////////////////////////////////////////////////////////////// .h文件templateclassTclassVector{public:// 加constsize_tsize()const;boolempty()const;Toperator[](size_t index);Tat(size_t index)const;voidpush_back(constTelem);};//////////////////////////////////////////////////////////////////////////// .cpp文件voidprintVec(constVectorintv){for(size_t i0;iv.size();i){std::coutv.at(i) ;}std::coutstd::endl;}// Compiler: “OK“const的作用告诉编译器保证不会在这个方法内部修改这个对象。确保在实现中也加上 const否则编译器会报错。templateclassTsize_tVectorT::size()const{returnlogical_size;}// Other methods...9.4.2 const接口// .cpptemplateclassTsize_tVectorT::size()const{// 这是一个const成员函数this-logical_size106;// 错误试图修改成员变量returnlogical_size;}这个错误的原因是在const成员函数中试图修改类的成员变量。在 C 中被声明为const的成员函数承诺不会修改类的任何成员变量编译器会对这一点进行严格检查。常量接口标记为常量的对象只能使用常量接口常量接口是指对象中为常量的函数templateclassTclassVector{public:size_tsize()const;boolempty()const;Toperator[](size_t index);Tat(size_t index)const;// 有两处错误voidpush_back(constTelem);};Tat(size_t index)const;voidoops(constVectorintv){v.at(0)42;// 由于v是const所以我们不能修改它}templateclassTclassVector{public:size_tsize()const;boolempty()const;Toperator[](size_t index);constTat(size_t index)const;// 还有一处错误voidpush_back(constTelem);};9.4.3 const重载让我们定义 at 方法的两个版本一个版本用于常量实例调用另一个用于非常量实例调用////////////////////////////////////////////////////////////////// .htemplateclassTclassVector{public:constTat(size_t index)const;Tat(size_t index);};////////////////////////////////////////////////////////////////// .cpptemplateclassTconstTVectorT::at(size_t index)const{returnelems[index];}templateclassTTVectorT::at(size_t index){returnelems[index];}再加一个函数findElement呢templatetypenameTTVectorT::findElement(constTvalue){for(size_t i0;ilogical_size;i){if(elems[i]elem)returnelems[i];}throwstd::out_of_range(Element not found);}templatetypenameTconstTVectorT::findElement(constTvalue)const{for(size_t i0;ilogical_size;i){if(elems[i]elem)returnelems[i];}throwstd::out_of_range(Element not found);}// 太繁琐了9.4.4 const_cast类型转换casting将一种类型转换为另一种类型的过程在 C 中有许多类型转换的方法const_cast 允许我们 “去除” 变量的常量性用法const_cast 目标类型 (表达式)那么这有什么用呢templatetypenameTTVectorT::findElement(constTvalue){for(size_t i0;ilogical_size;i){if(elems[i]elem)returnelems[i];}throwstd::out_of_range(Element not found);}templatetypenameTconstTVectorT::findElement(constTvalue)const{returnconst_castVectorT(*this).findElement(value);}何时用const_cast?简短回答几乎从不const_cast 告诉编译器“别担心我能搞定”。如果你需要一个可变值一开始就不要加 const。const_cast 的有效用法少之又少。9.4.5 mutableconst_cast 使整个对象变得可修改还有更细粒度的吗和const_cast一样mutable会规避const的保护机制请谨慎使用structMutableStruct{intdontTouchThis;mutabledoubleiCanChange;};constMutableStruct cm;// cm.dontTouchThis 42; // ❌ Not allowed, cm is constcm.iCanChange3.14;// ✅ Ok, iCanChange is mutablestructCameraRay{Point origin;Direction direction;mutableColor debugColor;}voidrenderRay(constCameraRayray){ray.debugColorColor.Yellow;// Show debug ray/* Rendering logic goes here ... */}使用案例存储调试信息structCameraRay{Point origin;Direction direction;mutableColordebugColor;}voidrenderRay(constCameraRayray){ray.debugColorColor.Yellow;// Show debug ray/* Rendering logic goes here ... */}
版权声明:本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!

分析网站做的好坏郑州专业网站推广公司

2025年12月,北京邮电大学脑认知与智能医学中心与清华大学材料学院合作,在国际知名期刊《npj Flexible Electronics》(中科院大类一区,IF15.5)上发表了题为“Cholinium-based eutectogel electrode for high-quality dy…

张小明 2025/12/21 22:32:26 网站建设

成都网站建设桔子集团网站制作

第一步:获取QQ邮箱的“授权码”(唯一需要做的事)登录你的QQ邮箱网页版。点击顶部 【设置】 → 【账户】。向下翻,找到 【POP3/IMAP/SMTP/Exchange/CardDAV/CalDAV服务】 这个部分。找到 【开启】POP3/SMTP服务 这一项,…

张小明 2025/12/21 22:28:22 网站建设

网站建设静态代码益阳哪里做网站

Linux USB Gadget驱动框架与类驱动详解 1. Gadget驱动框架基础 在Linux USB Gadget子系统中,Gadget驱动的实现通常与PDC驱动的实现相互关联。相关函数位于 drivers/usb/gadget/epautoconf.c 文件中,其定义在 include/linux/usb/gadget.h 里。以下是两个重要的函数: -…

张小明 2025/12/21 22:26:21 网站建设

做网站要招什么样的程序员品牌网站建设毛尖c

快速体验 打开 InsCode(快马)平台 https://www.inscode.net输入框内输入如下内容: 开发一个MinIO安全风险分析工具,要求:1. 自动扫描MinIO配置中的常见安全漏洞 2. 对比AWS S3等商业方案的安全特性差异 3. 生成可视化风险评估报告 4. 提供加…

张小明 2025/12/21 22:24:19 网站建设

换友链的网站云服务器网站建站

毕业设计实战:基于SSM的电影订票及评论网站,从技术选型到避坑的完整指南! 家人们谁懂啊!当初做电影订票网站毕设时,光“座位选座逻辑”就折腾了5天——一开始用字符串拼接存座位号,结果两个人同时选同一座…

张小明 2025/12/21 22:22:17 网站建设

免费文档网站辽宁建筑网

如何快速掌握BasePopup:Android弹窗开发的终极指南 【免费下载链接】BasePopup Android下打造通用便捷的PopupWindow弹窗库 项目地址: https://gitcode.com/gh_mirrors/ba/BasePopup 在Android应用开发过程中,弹窗功能几乎是不可或缺的组件。无论…

张小明 2025/12/21 22:20:15 网站建设