C++系列笔记(八)

简介: C++系列笔记(八)

导读】《21天学通C++》这本书通过大量精小短悍的程序详细而全面的阐述了C++的基本概念和技术,包括管理输入/输出、循环和数组、面向对象编程、模板、使用标准模板库以及创建C++应用程序等。这些内容被组织成结构合理、联系紧密的章节,每章都可在1小时内阅读完毕,都提供了示例程序清单,并辅以示例输出和代码分析,以阐述该章介绍的主题。本文是系列笔记的第八篇,欢迎各位阅读指正!              

模板简介


模板声明以关键字template打头,接下来是类型参数列表。这种声明的格式template <parameter list>示例代码如下:

#include<iostream>#include<string>usingnamespacestd;
template<typenameType>constType&GetMax(constType&value1, constType&value2)
{
if (value1>value2)
returnvalue1;
elsereturnvalue2;
}
template<typenameType>voidDisplaycomparison(constType&value1, constType&value2)
{
cout<<"GetMax("<<value1<<","<<value2<<")=";
cout<<GetMax(value1, value2) <<endl;
}
intmain()
{
inta1=-101, inta2=2011;
Displaycomparison(a1, a2);
doubled1=3.14, doubled2=3.1415926;
Displaycomparison(d1, d2);
stringName1("Jack"), Name2("john");
Displaycomparison(Name1, Name2);
return0;
}

模板函数不仅可以重用(就像宏函数一样),而且更容易编写和维护,还是类型安全的。请注意,调用Displaycomparison时,也可显式地指定类型,如下所示:

Displaycomparison<int>(Int1,Int2);

然而,调用模板函数时没有必要这样做。您无需指定模板参数的类型,因为编译器能够自动推断出类型;但使用模板类时,需要这样做。

模板类


模板类是模板化的 C++类,是蓝图的蓝图。使用模板类时,可指定要为哪种类型具体化类。这让您能够创建不同的Human对象,即有的年龄存储在 long long成员中,有的存储在 int成员中,还有的存储在short成员中。对于模板,术语实例化的含义稍有不同。用于类时,实例化通常指的是根据类创建对象。但用于模板时,实例化指的是根据模板声明以及一个或多个参数创建特定的类型。对于下面的模板声明:

template<typenameT>classTemplateClass{
Tm_member;
};

使用模板是将这样编写代码

TemplateClass<int>IntTemplate;

这种实例化创建的特定类型称为具体化。

声明包含多个参数的模板


如下面代码所示:

template<typenameT1, typenameT2>classHoldsPair{
private:
T1Value1;
T2Value2;
public:
HoldsPair(constT1&value1,constT2&value2)
    {
Value1=value1;
Value2=value2;
    }
//other function declarations};

实例化如下:

HoldsPair<int,double>pairIntDouble(6,1.99);
HoldsPair<int,int>pairIntDouble(6,500);

包含默认参数的模板


template<typenameT1=int,typenameT2=int>classHoldsPair{
//……method declare};

实例化可简写为:

HoldsPair<>PairIntDouble(6,500);

实例代码如下:

#include<iostream>usingnamespacestd;
template<typenameT1=int,typenameT2=double>classHoldsPair{
private:
T1Value1;
T2Value2;
public:
HoldsPair(constT1&value1, constT2&value2)
        {
Value1=value1;
Value2=value2;
        };
constT1&GetFirstvalue() const        {
returnValue1;
        };
constT2&GetSecondvalue() const        {
returnValue2;
        };
};
intmain()
{
HoldsPair<>mIntFloatPair(300, 10.09);
HoldsPair<short,constchar*>mshortstringPair(25, "learn template,love c++");
cout<<"the first object conntains-"<<endl;
cout<<"Value 1:"<<mIntFloatPair.GetFirstvalue() <<endl;
cout<<"Value 2:"<<mIntFloatPair.GetSecondvalue() <<endl;
cout<<"the second object contains-:"<<endl;
cout<<"Value 1:"<<mshortstringPair.GetFirstvalue() <<endl;
cout<<"Value 2:"<<mshortstringPair.GetSecondvalue() <<endl;
return0;
}

输出为:

thefirstobjectconntains-Value1:300Value2:10.09thesecondobjectcontains-:
Value1:25Value2:learntemplate,lovec++

模板类和静态成员


实例代码如下:

#include<iostream>usingnamespacestd;
template<typenameT>classTestStatic{
public:
staticintStaticValue;
};
template<typenameT>intTestStatic<T>::StaticValue;
intmain()
{
TestStatic<int>Int_Year;
cout<<"setting staticvalue for Int_Year to 2011"<<endl;
Int_Year.StaticValue=2011;
TestStatic<int>Int_2;
TestStatic<double>Double_1;
TestStatic<double>Double_2;
cout<<"setting staticvalue for Double_2 to 1011"<<endl;
Double_2.StaticValue=1011;
cout<<"Int_2.StaticValue= "<<Int_2.StaticValue<<endl;
cout<<"Double_1.StaticValue= "<<Double_1.StaticValue<<endl;
return0;
}

输出为:

settingstaticvalueforInt_Yearto2011settingstaticvalueforDouble_2to1011Int_2.StaticValue=2011Double_1.StaticValue=1011

上述有一条程序初始化模板类的静态成员:template<typename T> int TestStatic<T>::StaticValue*对于模板类的静态成员,通用的初始化语法如下:

template<typenameparameters>staticTypeClassName<TemplateArugments>::StaticVarName;

使用static_assert执行编译阶段检查


tatic_assert是C++11新增的一项功能,让您能够在不满足指定条件时禁止编译。语法如下:

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!");

示例代码如下

#include<iostream>usingnamespacestd;
template<typenameT>classeverythingbutInt{
public:
everythingbutInt()
        {
static_assert(sizeof(T) !=sizeof(int), "Not int please!");
        }
};
intmain()
{
everythingbutInt<int>test;
return0;
}


相关文章
|
5月前
|
算法 C++
算法笔记:递归(c++实现)
算法笔记:递归(c++实现)
|
5月前
|
编译器 C++
《Effective C++ 改善程序与设计的55个具体做法》 第一章 笔记
《Effective C++ 改善程序与设计的55个具体做法》 第一章 笔记
|
3月前
|
C++ 容器
【C/C++笔记】迭代器
【C/C++笔记】迭代器
22 1
|
3月前
|
存储 安全 程序员
【C/C++笔记】迭代器范围
【C/C++笔记】迭代器范围
63 0
|
4月前
|
C++ Windows
FFmpeg开发笔记(三十九)给Visual Studio的C++工程集成FFmpeg
在Windows上使用Visual Studio 2022进行FFmpeg和SDL2集成开发,首先安装FFmpeg至E:\msys64\usr\local\ffmpeg,然后新建C++控制台项目。在项目属性中,添加FFmpeg和SDL2的头文件及库文件目录。接着配置链接器的附加依赖项,包括多个FFmpeg及SDL2的lib文件。在代码中引入FFmpeg的`av_log`函数输出"Hello World",编译并运行,若看到"Hello World",即表示集成成功。详细步骤可参考《FFmpeg开发实战:从零基础到短视频上线》。
113 0
FFmpeg开发笔记(三十九)给Visual Studio的C++工程集成FFmpeg
|
6月前
|
存储 C++ 容器
黑马c++ STL部分 笔记(7) list容器
黑马c++ STL部分 笔记(7) list容器
|
6月前
|
算法 C++ 容器
黑马c++ STL常用算法 笔记(5) 常用算术生成算法
黑马c++ STL常用算法 笔记(5) 常用算术生成算法
|
6月前
|
算法 C++ 容器
黑马c++ STL常用算法 笔记(4) 常用拷贝和替换算法
黑马c++ STL常用算法 笔记(4) 常用拷贝和替换算法
|
6月前
|
存储 算法 搜索推荐
黑马c++ STL常用算法 笔记(3) 排序算法
黑马c++ STL常用算法 笔记(3) 排序算法
|
6月前
|
算法 C++
黑马c++ STL常用算法 笔记(2) 查找算法
黑马c++ STL常用算法 笔记(2) 查找算法