热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

C++学习Day.9(宏和模板简介)

好久没更了,摆还是爽遗留问题:(16条消息)int&作为函数返回类型-编程语言-CSDN问答(已解决)宏:

好久没更了,摆还是爽

遗留问题:

(16条消息) int&作为函数返回类型-编程语言-CSDN问答(已解决)


宏:


预处理器编译指令都以#打头 


#define(宏常量)使得预处理器进行文本替换,而不考虑其他,编译器将检查文本正确与否。    不解风情

 宏需要大量括号,凡变量尽量都打一括号。

列如:

#define i* int*
i* a,b;
此时我们的本意是 int *a,*b;
而实际上的代码为 int *a, b;
此时的 b 为 int 型,而非 int* 型

使用宏避免多次包含

reference:

(6条消息) #ifndef,#define,#endif的作用和用法_Junzheng Li的博客-CSDN博客

(7条消息) #ifndef/#define/#endif使用详解_ 司 的博客-CSDN博客_#ifndef _a_h_

例:

 assert宏:验证表达式

语法:

assert (expression that evaluates to true or false);

包含:于头文件

示例:

#include
int main()
{ char* sayHello = new char [25]; assert(sayHello != NULL); // throws a message if pointer is NULL // other code delete [] sayHello; return 0;
}

在我的DEV编译器中出现如下报错:

注: 

 宏不支持任何形式的类型安全,这是一个严重的缺点。另外,复杂的宏调试起来也不容易


 模板:

template:n. 样板;模板;型板

声明模板以关键字template打头 

//模板类,使用需要
template
class HoldVarTypeT
{
private: T value;
public: void SetValue (const T& newValue) { value = newValue; } T& GetValue() {return value;}
};

 instantiation :实例化

template
class HoldsPair
{
private: T1 value1; T2 value2;
public: // Constructor that initializes member variables HoldsPair (const T1& val1, const T2& val2) { value1 = val1; value2 = val2; }; // ... Other member functions
};

 实例化:

HoldsPair pairIntDouble (6, 1.99);
HoldsPair pairInts (6, 500);

声明包含默认参数的模板


可以修改前面的 HoldsPair <>,将模板参数的默认类型指定为 int


template
class HoldsPair
{
// ... method declarations
};


这与给函数指定默认参数值极其类似,只是这里指定的是默认类型。

这样,前述第二种 HoldsPair 用法可以简写为:

// Pair an int with an int (default type)
HoldsPair <> pairInts (6, 500);

#include
using namespace std;template
class HoldsPair {private:T1 value1;T2 value2;public:HoldsPair(const T1& val1, const T2& val2) // constructor: value1(val1), value2(val2) {}// Accessor functionsconst T1& GetFirstValue() const {cout <<"fanhui double " <};// specialization of HoldsPair for types int & int here
template<> class HoldsPair {private:int value1;int value2;string strFun;public:HoldsPair(const int& val1, const int& val2) // constructor: value1(val1), value2(val2) {}const int & GetFirstValue() const {cout <<"Returning integer " <};int main() {HoldsPair pairIntInt(222, 333); //在类型为int,int时调用第二个,否则调用第一个pairIntInt.GetFirstValue();return 0;
}

模板类的具体化,如上。

模板类和静态成员

示例代码:

#include
using namespace std;template
class TestStatic {public:static int staticVal;
};// static member initialization
template int TestStatic::staticVal;int main() {TestStatic intInstance;cout <<"Setting staticVal for intInstance to 2011" < dblnstance;cout <<"Setting staticVal for Double_2 to 1011" <



Q:静态变量有啥用?


假定您要编写一个将两个值相加的通用函数,为此可编写下面这样的模板函数 Sum()

template
void Sum(T1& result, T2 num1, T3 num2)
{
result = num1 + num2;
return;
}

想要加上不同的值应如下进行编码:参变量可变的模板


#include
using namespace std;template
void Sum(R& result,V& val){result+=val;cout<<"i have in prime"<}template
void Sum(R& result, First val1, Rest...valN) {result += val1;return Sum(result, valN...);
}int main() {double dResult = 0;Sum(dResult, 3.14, 4.56, 1.1111);cout<<"dResult"<

注:必须要有基础模板


实例化并使用 std::tuple

引用:(3条消息) C++的get()函数使用详解_Nine_CC的博客-CSDN博客_c++ get

使用static_assert();


static_assert C++11 新增的一项功能,让您能够在不满足指定条件时禁止编译。这好像不可思议,但对模板类来说很有用。例如,您可能想禁止针对 int 实例化模板类,为此可使用 static_assert,它是一 种编译阶段断言,可用于在开发环境(或控制台中)显示一条自定义消息:


static_assert(expression being validated, "Error message when check fails");


要禁止针对类型 int 实例化模板类,可使用 static_assert( ),并将 sizeof(T)sizeof(int)进行比较,如果它们相等,就显示一条错误消息:

static_assert(sizeof(T) != sizeof(int), "No int please!");

如图:

DEV编译器报错为: 



学习本章介绍的模板知识后,便为学习如何使用 STL 做好了准备!


问:在头文件中,为何要防范多次包含?

答:多次包含防范使用#ifndef#define #endif,可避免头文件出现多次包含或递归包含错误,有时还可提高编译速度。


问:如果所需的功能使用宏函数和模板都能实现,在什么情况下应使用宏函数,而不是模板?

答:在任何情况下都应使用模板,而不是宏函数,因为模板不但提供了通用实现,还是类型安全

的。宏函数不是类型安全的,最好不要使用。


问:调用模板函数时,需要指定模板参数类型吗?

答:通常不需要,因为编译器能够根据函数调用使用的实参推断出模板参数类型。


问:对于特定模板类,每个静态成员有多少个版本?

答:这完全取决于针对多少种类型实例化了该模板类。如果针对 intstring 和自定义类型 X 实例

化了该模板类,则每个静态成员都有三个不同的版本每种模板实例化一个。

编写模板函数Display,它可调用不同数量和类型的的参数并显示。

#include
using namespace std;template
void Display(t0& e0) {cout <<"different from xiamian de , i will be used when the en is used\that&#39;s to say , the element en won&#39;t be used int this case" <
void Display(t0& e0, other...en) {cout <}int main() {string a = "fu huo ba", b = "wo";string c = "de", d = "ai", f = "ren";Display(a, b, c, d, f, "hhh");return 0;
}

 运行结果:

 

一版和上面稍有不同的代码:

#include
using namespace std;void Display() {cout <<"i will be use at last,when all the elements are use\even Display(en)" <}template
void Display(t0& e0, other...en) {cout <}int main() {string a = "fu huo ba", b = "wo";string c = "de", d = "ai", f = "ren";Display(a, b, c, d, f, "hhh");return 0;
}

运行结果: 

 


推荐阅读
  • 本文讨论了一个关于cuowu类的问题,作者在使用cuowu类时遇到了错误提示和使用AdjustmentListener的问题。文章提供了16个解决方案,并给出了两个可能导致错误的原因。 ... [详细]
  • Linux环境变量函数getenv、putenv、setenv和unsetenv详解
    本文详细解释了Linux中的环境变量函数getenv、putenv、setenv和unsetenv的用法和功能。通过使用这些函数,可以获取、设置和删除环境变量的值。同时给出了相应的函数原型、参数说明和返回值。通过示例代码演示了如何使用getenv函数获取环境变量的值,并打印出来。 ... [详细]
  • 本文介绍了PE文件结构中的导出表的解析方法,包括获取区段头表、遍历查找所在的区段等步骤。通过该方法可以准确地解析PE文件中的导出表信息。 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • Iamtryingtomakeaclassthatwillreadatextfileofnamesintoanarray,thenreturnthatarra ... [详细]
  • VScode格式化文档换行或不换行的设置方法
    本文介绍了在VScode中设置格式化文档换行或不换行的方法,包括使用插件和修改settings.json文件的内容。详细步骤为:找到settings.json文件,将其中的代码替换为指定的代码。 ... [详细]
  • Java容器中的compareto方法排序原理解析
    本文从源码解析Java容器中的compareto方法的排序原理,讲解了在使用数组存储数据时的限制以及存储效率的问题。同时提到了Redis的五大数据结构和list、set等知识点,回忆了作者大学时代的Java学习经历。文章以作者做的思维导图作为目录,展示了整个讲解过程。 ... [详细]
  • eclipse学习(第三章:ssh中的Hibernate)——11.Hibernate的缓存(2级缓存,get和load)
    本文介绍了eclipse学习中的第三章内容,主要讲解了ssh中的Hibernate的缓存,包括2级缓存和get方法、load方法的区别。文章还涉及了项目实践和相关知识点的讲解。 ... [详细]
  • Go Cobra命令行工具入门教程
    本文介绍了Go语言实现的命令行工具Cobra的基本概念、安装方法和入门实践。Cobra被广泛应用于各种项目中,如Kubernetes、Hugo和Github CLI等。通过使用Cobra,我们可以快速创建命令行工具,适用于写测试脚本和各种服务的Admin CLI。文章还通过一个简单的demo演示了Cobra的使用方法。 ... [详细]
  • Nginx使用(server参数配置)
    本文介绍了Nginx的使用,重点讲解了server参数配置,包括端口号、主机名、根目录等内容。同时,还介绍了Nginx的反向代理功能。 ... [详细]
  • Commit1ced2a7433ea8937a1b260ea65d708f32ca7c95eintroduceda+Clonetraitboundtom ... [详细]
  • 阿,里,云,物,联网,net,core,客户端,czgl,aliiotclient, ... [详细]
  • 本文介绍了C++中省略号类型和参数个数不确定函数参数的使用方法,并提供了一个范例。通过宏定义的方式,可以方便地处理不定参数的情况。文章中给出了具体的代码实现,并对代码进行了解释和说明。这对于需要处理不定参数的情况的程序员来说,是一个很有用的参考资料。 ... [详细]
  • 本文主要解析了Open judge C16H问题中涉及到的Magical Balls的快速幂和逆元算法,并给出了问题的解析和解决方法。详细介绍了问题的背景和规则,并给出了相应的算法解析和实现步骤。通过本文的解析,读者可以更好地理解和解决Open judge C16H问题中的Magical Balls部分。 ... [详细]
  • 本文介绍了在满足特定条件时如何在输入字段中使用默认值的方法和相应的代码。当输入字段填充100或更多的金额时,使用50作为默认值;当输入字段填充有-20或更多(负数)时,使用-10作为默认值。文章还提供了相关的JavaScript和Jquery代码,用于动态地根据条件使用默认值。 ... [详细]
author-avatar
xuxiao
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有