首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

【笔记】《C++Primer》—— 第三部分:类设计者的工具

构造函数来类型转换,则拷贝初始化还是直接初始化就无关紧要了 析构函数的行为与构造函数相反,会自动销毁掉非static的成员和调用成员析构 析构函数没有参数列表,所以成员销毁时的行为完全依赖于成员自己 析构会在变量离开作用域或母构件销毁时销毁...因此除了重载虚函数外最好不要让名称同名 派生类可以覆盖基类重载的函数,但是如果派生类希望基类重载的几个函数都在派生类中可见的话:一种方法覆盖任何一个重载函数或将所有重载函数都进行一次覆盖;另一种方法为需要重载的函数名使用...,这些实参不会被继承,而是派生类会得到多个继承的构造函数,每个构造函数省略一个有默认实参的形 当我们想要把继承体系的对象存放到容器中时,最好使用间接存储也就是存放基类指针(智能指针就更好了) 16...类模板不会推断参数类型模板的成员函数只有在使用时才会实例化 类模板与另一个模板直接最常见的友元一对一的友元,首先模板需要声明所有需要用到的名字,然后在声明友元时标注出目标类的具体模板实参 类模板也可以一对多友元...要注意如果声明了目标友元的模板实参标识符,这些标识符需要与自身类模板的标识符不同 我们不能用typedef来起模板类型别名,但是C11让我们可以用using来起模板类型别名 C11允许我们为函数模板和类模板提供默认参数

1.7K10

读完某C++神作,我只记下了100句话

变量声明还是定义看是否有extern,但不是绝对的,函数就看有无大括号{} 两个迭代器指向同一个元素就相等【==】,否则不等。任何改变vector长度的操作都会使已存在的迭代器失效。...T>模板定义以关键字template开始【旧程序中可能用class】,后接模板表,模板由尖括号扩住的一个多个模板的列表,以逗号分隔。...泛型代码两个原则:1.模板const引用 2.函数体中只用<比较 模板参数量自由,可以设定返回值为一个。...模板类中的static成员由同一实例化的对象共享,但不同模板的实例化对象间共享。...模板特化:template 模板名函数形表 函数体 特化类 也可以只特化类中某个成员 部分特化:多个模板,特化某个形【编译器会优先选择特化的】。

1.4K20
您找到你想要的搜索结果了吗?
是的
没有找到

《Effective C++》学习笔记

return *this; } 条款11:在 operator= 中处理“自我赋值” 由于变量有别名的存在(多个指针或引用只想一个对象),所以可能出现自我赋值的情况。...解决方案将该乘法运算函数作为一个非成员函数,传两个参数进去,这样不管你的int放在前面还是后面,都能作为参数被转换类型了。...Handle classes一个声明类,一个imp实现类,声明类中涉及具体的定义,只有接口声明,在定义类中include声明类,而不是继承。...做法声明一个泛化构造函数,也就是定义一个模板构造函数,接收模板参数声明一个指向的真实对象指针,声明一个获取该对象指针的get函数,用该get函数放在初始化列表中来构造模板类。...虽然这种模板构造函数也能作为复制构造函数使用(用相同类型来构造即可),但编译器还是会当做你没有声明复制构造函数,从而为你创建一个,因此如果想要彻底控制行为,你还是需要自行声明你的复制构造函数和赋值构造函数

1.1K20

C++模板初阶

2.类模板不能声明定义分离 非类型模板参数 泛型编程 在一个项目中,我们可能需要交换不同类型的数据。...2.不同类型的传处理 1.强制类型转换 既然函数模板编译器根据我所传的参数自动推演而来,那么一个函数模板是否可以处理两个不同类型参数呢?...所以只要对参数加上const就可以使这段代码成功跑过: 2.显示实例化 除了强制类型转换以外,还可以在传时对模板参数显示实例化明确的告诉编译器应当产生什么类型的函数,这个时候如果传两个不同类型...上述的模板中,只使用了一个模板参数,所以也就是一个函数模板只能同时对一个类型进行推演,但是如果在函数模板中使用多个参数,自然就可以同时对不同的类型进行推演: template <typename T1...,编译器有足够的泛型参数对两个不同的类型进行推演,不过返回值还是只能两个类型中的一个

61500

C++进阶:C++11(列表初始化、右值引用与移动构造移动赋值、可变参数模版...Args、lambda表达式、function包装器)

它通常与 auto 结合使用,用于声明变量的类型或者作为模板参数推断的一部分。...那么如果右值引用本身还是右值,不能被改变,那还怎么进行资源的转移 const 右值 ,右值引用后不能改变 万能引用是 C++11 中引入的一种引用类型,用于实现泛型编程时处理模板类型参数的值类别...万能引用的语法 T&&,其中 T 模板类型参数。当万能引用绑定到一个右值时,它被推导为右值引用;当绑定到一个左值时,它被推导为左值引用。...一个基础的模版: // Args一个模板参数包,args一个函数形参数包 // 声明一个参数包Args...args,这个参数包中可以包含0到任意个模板参数。..._ShowArgs(args...); } // Args一个模板参数包,args一个函数形参数包 // 声明一个参数包Args...args,这个参数包中可以包含0到任意个模板参数

7000

【C++系列(合集)】特性多又复杂?不存在!——这篇C++大全直接干碎(超级大全,精讲)

虽然有多个参数,但是创建对象时后两个参数可以传递,没有使用explicit修饰,具有类型转 换作用 // explicit修饰构造函数,禁止类型转换 explicit Date(int year,...(const Date d); 直接进行调用; d2传给没有显示的this指针,d1传给const Date d; Date d2(const Date d1) 拷贝构造函数的参数只有一个且必须类型对象的引用...1.函数模板 一.函数模板概念 函数模板代表了一个函数家族,该函数模板类型无关,在使用时被参数化,根据实参类型产生函数的特定类型版本。...如果模板可以产生一个具有更好匹配的函数, 那么将选择模板 模板函数不允许自动类型转换,但普通函数可以进行自动类型转换 2.类模板 一.类模板的格式 template s1; Vector s2; 注意区分: 在类中:类名等同于类型 在类模板中:类型类型,类名类名 例如:在下面代码中,类模板中函数放在类外进行定义时,

16610

C++打怪升级(八)- 泛型编程初见

---- 泛型编程 引子 对于一组功能相同单参数类型不同的函数,在C语言中只能写多个不同名的函数来实现; void Swapc(char& a, char& b) { char tmp = a; a...b = tmp; } void Swapf(float& a, float& b) { float tmp = a; a = b; b = tmp; } 在C++中我们学习了函数重载,可以写多个同名参数类型不同的函数来实现...不同类型参数使用函数模板时,生成不同类型的函数称为函数模板的实例化; 分为隐式实例化和显式实例化; 隐式实例化 由编译器在编译阶段根据我们所传实参推导函数模板参数实际类型然后生成某一具体类型的函数...也只能推导出一个具体的类型,这样就总会有一个实参类型匹配不上; 这里的报错编译器无法根据实参类型明确推导出一个具体的函数了,涉及类型转换(发生在具体的函数传时); //函数模板 template...原因分析 类模板分离编译会报链接错误 一般建议类模板在同一个文件中声明和定义分离,这是最好的方式了,达到了类中简洁只有函数声明,同时没有各种错误; 来看看类声明和定义分离且不在一个文件会遇到的问题

79520

【C++】模板进阶

;而非类型则是用一个常量作为类模板/函数模板一个参数,在类模板/函数模板中可将该参数当成常量来使用。...C++ 中设计了非类型模板参数来解决了这个问题,如下,我们可以通过传递不同的非类型来定义不同的类,非类型模板参数在函数模板中的使用也是如此: template...-- 确实,由于函数支持重载,所以我们完全可以将重载一个/多个特殊类型的形;所以,一般情况下如果函数模板遇到不能处理或者处理有误的类型,为了实现简单通常都是将该函数直接给出 (函数重载)。...,比如模板参数定义为 ,这样只要实参为指针类型,不管 int*、double*、还是 vector*,都会调用此特化模板;又比如将模板参数定义为为 ,这样只要实参引用类型就会调用此特化模板...所以,模板不支持分离编译,我们一般采用其他的解决办法,如下: 1、模板函数不进行声明,直接在类里面给出函数的定义;(如果类很大时这种方法不方便别人阅读我们的代码,推荐使用;当类较小时可以这样做,比如我们之前模拟实现的

43100

【C++】初识模板

就好像下面这样: 我们可以看到,我们通过给这个模子不同的材料,从而得到由不同材料铸成的不同结果,但是本身还是一个爱心,只不过材料不同。本次章节所讲解的模板,作用就类似于图纸里的这些“模子”。...而模板,则是泛型编程的基础,我们可以通过模板,来实现虽然类型不同(橡皮泥颜色各异),但最终目的相同(都是得到爱心,只不过不一样的爱心,红黄蓝绿...)。...所以会报错(编译器也很懵逼,这个T到底int,还是double???)...(注意一点,强制类型转换会产生临时变量,临时变量具有常性,所以我们的形得需要const来修饰) 显式实例化 我们可以在函数名后的中指定模板参数的实际类型,告诉编译器,这个T到底啥。...如下: Add(a1,d2);//告诉编译器,T的类型为int 此时如果类型匹配,编译器会尝试进行隐式类型转换,如果无法转换成功编译器将会报错。

53530

【笔记】C++2.0新特性

因此如果目标模板多个参数但是我们只想传递一个参数的话, 可以利用模板别名将默认值进行包装, 从而减少需要传递的模板参数数量....和Lambda中, 替代了旧版本中不好用的typeof 返回值: 在模板编程中, 我们不仅希望能自动推导参数类型, 还希望按照得到类型来推导返回值, 如今可以借助尾置返回将模板函数写为下面的形式....右值引用依然一种引用, 其并不会改变对象的声明周期, 真正改变声明周期的还是我们自己的操作....这里要注意如上一点, 函数此时的形类型右值引用的声明, 一个左值 平时我们写普通函数由于参数版本都需要提前设置好所以不用担心引用属性改变的问题, 但是在模板函数中有不同的情况: 对于模板函数的实参推导来说..., 目的针对上面的模板代码的情况, 如果推断的模板参数本身就带有引用, 叠加后需要消除多余的引用: T& & -> T& T& && -> T& 在折叠规则中可以看到不管实参是什么类型, 除非形右值引用

88520

【c++入门】引用详解 | auto的类型推导 | 范围for循环 | nullptr空指针

本篇会对这些进行细致的讲解,以帮助大家更好的了解c++语法。 ️引用 ​ 你有没有被人起过外号?...⭐一个变量可以有多个引用 此时这些引用都是n的别名,指向的就是n,和n共用一块空间!...☁️auto使用细节 ⭐auto与指针和引用结合起来使用 用auto声明指针类型时,用auto和auto*没有任何区别,但用auto声明引用类型时则必须加& ⭐在同一行定义多个变量 当在同一行声明多个变量时...void foo(auto x); // 错误,auto 不能用于函数参数类型声明模板参数 模板参数类型在实例化时确定的,编译器无法在编译时推导出模板参数类型。...template void foo(auto x); // 错误,auto 不能用于模板参数类型声明 ⭐类成员变量 类成员变量的类型在类定义时确定的,编译器无法在编译时推导出类成员变量的类型

18010

c++11增加的变参数模板,今天总算整明白了

那么所有的模板声明类型都可以作为函数形类型吗,不是的,前面我们讲了三种模板包,这其中除了非类型模板包因为类型固定且具体的值,不能作为函数形包以外,类型模板包和模板模板包因为声明的都是类型...,说白了,我们要理解函数形包的本质,它其实还是一个函数形,既然函数形,就脱离不了类型参数名的语法,形包无非就是在类型后面加个省略号,而模板模板包作为函数形类型的时候一定要记得加模板参数...比如上面的age ...和Fargs...都属于包展开,但是要知道,这种形式我们没有办法直接使用的,那么具体该怎么使用呢,有两种办法: 一使用递归的办法把形包里面的参数一个一个的拿出来进行处理,最后以一个默认的函数或者特化模板类来结束递归...递归方法适用场景:多个不同类型和数量的参数有比较相似的动作的时候,比较适合使用递归的办法。 关于递归办法的使用,前面几节有多个案例了,这里不再展开多说。...__args到底代表什么呢,抛开右值引用不说,它就是多个参数,难道可以在容器中插入多个不同类型的元素吗,并不是啊,容器中的元素必须要一致的,这里的参数其实是容器定义时元素类型构造函数的多个参数,也就是说

2.1K20

C++基础知识概述

6.缺省参数 缺省参数概念: 缺省参数 声明或定义函数时 为函数的 参数指定一个缺省值 。在调用该函数时,如果没有指定实 则采用该形的缺省值,否则使用指定的实参。...7.函数重载 函数重载的定义: 函数重载函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形列表(参数个数或类型类型顺序不同),常用来处理实现功能类似数据类型不同的问题...7.如果两个函数名和参数一样的,返回值不同是构成重载的,因为调用时编译器没办法区分,避免调用的二义性。...在同一行定义多个变量 当在同一行声明多个变量时,这些变量必须相同的类型,否则编译器将会报错,因为编译 器实际只对第一个类型进行推导,然后用推导出来的类型定义其他变量 。...不能推导的场景: 1.auto不能作为函数的参数: // 此处代码编译失败,auto不能作为形类型,因为编译器无法对a的实际类型进行推导 void TestAuto(auto a) {} 2.auto

97320

【笔记】《深入理解C++11》(上)

, 且如果不被使用就不会生成 继承构造函数的默认参数不会被继承, 反而会生成多个不同声明的构造函数的产生, 所以当发生冲突的时候应该显式声明构造函数来因此冲突的函数 当派生类虚继承了基类时, 不能使用继承构造函数...大括号初始化会制止类型收窄 大括号的返回值initializer_list, 可以用作函数的一种重载参数 大括号也可以在return, 一般用来构造临时变量, 具体构造出来的临时变量还是依靠声明的返回值决定...函数模板据我们的实参类型在调用时进行特化并实例化的, 具体来说匹配遵循以下步骤: 首先对于一次调用, 编译器查找所有具有此名称的函数和实例化的模板函数表 在这些函数中进行比较, 将不可行的函数剔除,...auto无法带走变量的cv限制, 因此需要我们额外写清楚对应的限制 auto可以用来在一个表达式中声明多个变量, 此时这些变量的类型必须相同且都是第一个变量的类型 auto的类型推导式从左到右进行的,...由于类似字符替换的特性, 表达式auto t = 1, &r = t, *p = &r;合法的 auto不能作为形类型, 需要泛型的时候还是应该用模板处理 auto禁止对结构体中的非静态成员进行推导

1.9K20

C++11 变模板

1.概述 变模板(variadic template)C++11新增的最强大的特性之一,它对参数进行了高度泛化,它能表示0到任意个数、任意类型参数。...2.可变模版参数的展开 可变模板参数和普通模板参数的语义一样的,只是写法上稍有区别,声明可变参数模板时需要在typename或class后面带上省略号“…”。...展开函数参数包的方法一般有两种:一种通过递归函数来展开参数包,另外一种通过逗号表达式来展开参数包。...下面看一下展开变模板中的参数包的方法。 2.2.1偏特化与递归方式展开 变模板的展开一般需要定义两到三个类,包括类声明和偏特化的类模板。...fun1 = Fun1;//编译报错,参数类型匹配 这里不能泛化的原因声明委托类型的时候就限定了参数类型和个数,在C++11里不存在这个问题了,因为有了可变模版参数,它就代表了任意类型和个数的参数

3.3K51

【C++】模板进阶

模板参数分为类型模板参数和非类型模板参数类型模板参数一般class或typename定义出来的泛型,而非类型模板参数一般整型定义出来的常量,这个常量作为类模板或函数模板一个参数,在类模板或函数模板中可将该参数当成常量来使用...在C语言阶段如果想要让数组的大小可以自己控制,一般都会用定义宏的方式来解决,在C++中我们可以使用非类型模板参数来进行解决,下面代码给出类模板声明,在使用时我们可以显示实例化类模板,给非类型模板参数一个常量...非类型模板参数声明时的类型必须只能整型,其他例如自定义类型,字符串类型,浮点型等类型均不能作为非类型模板参数类型声明,只有整型才可以。 4....在函数模板特化时,必须要先有一个基础的函数模板,然后在特化的函数上一行加一个template,然后在函数名后面加尖括号,尖括号里面指定特化的类型,特化函数的形表必须要和原来的函数模板的形表所包含的基础参数类型匹配...部分特化后的模板属于办成品,如果在传时,某一个参数属于部分特化后的参数,则编译器优先调用那个部分特化的类模板

1K20

【C++】模板进阶

1.非类型模板参数 模板参数分为 类型 和 非类型 类型即出现在模板参数列表中, 跟在class或者typename之类的参数类型名称 非类型:就是用一个常量作为类(函数)模板一个参数...,虽然看似可以解决问题,但若a要10个int的数组,b要100个double的数组,宏就没办法解决了 ---- 所以为了解决这个问题,引入非类型模板参数,定义的常量,一般整形常量 ---- #include...,但是只特化了一个 ,无论传的 int、int*、double 都是走到半特化 参数的进一步限制 两个参数特化为引用类型 两个参数特化为指针类型 3....模板的分离编译 模板并不支持分离编译 即声明一个文件,定义在一个文件 此时调用模板add 就会报错,因为模板声明和定义不在同一文件中 ---- 调用普通函数func,即可正常运行 模板会发生链接错误...模板总结 缺陷 1. 模板会导致代码膨胀问题,也会导致编译时间变长 模板进行实例化,所以运行时间变长,因为一个模板,若传过来int 、char、double 类型都要实现,所以代码会膨胀 2.

20030

第6章 函数

解决办法就是在 .h文件中仅包含函数声明,函数实现放到 .cpp文件中去。 ---- 6.2 参数传递 形初始化的机理与变量初始化一样。...C++中一个函数只能返回一个值,而当函数需要返回多个值时,可以通过引用和指针形来完成。这样的话,输入参数在函数执行完毕后也会被改变,也就相当于是一个输出参数了。...当然,还可以通过自定义一个数据类型或使用 tuple模板来返回多个值。 与变量初始化一样,参数初始化时,会忽略掉顶层 const。因此对下式传给它常量对象或者非常量对象都是可以的。...因为作为形, compare或 pf只是形的名字,与之前已经声明的同名名字没有关系。另外,作为形表达式,整体的意义一个类型。所以使用类型别名可以简化代码,增强可读性。...不能返回一个函数,但可以返回函数指针。与返回数组指针一样,也还是这四种返回方式。 直接声明。 int (*f1(int)) (int*, int); 类型别名

1.2K70

【C++】泛型编程——模板进阶

类型模板参数我们已经了解了: 类型即:出现在模板参数列表中,跟在class或者typename关键字之后的参数类型名称。 那非类型模板参数又是什么呢? 2....那大家来思考一下: 首先对于类型模板参数来说,他解决了类型的问题。...其实可以认为就是静态数组,我们看到文档给的解释固定大小的序列容器 我们看到array这个类模板其实就用了一个类型模板参数来作为这个数组的大小。...当然如果我们比Date*的话,还是比较的地址的大小,如果我们想让他比较指针指向的数据的大小,我们可以对Date* 这个类型进行一个特化(那在这里其实就是一个全特化)。...但是我们发现,这种方法的,增加一个类型,我们就要增加一个显式实例化,很麻烦。 所以推荐这种方法。 那有没有好一点的方法呢?有的 声明和定义可以分离,但放到一个文件中 什么意思呢?

20810

【笔记】《C++Primer》—— 第16章:模板与泛型编程

在起类型别名时我们会将整个模板类作为一个别名,其中我们可以将一些参数固定住 // 类模板的全参数别名 template using shortTemp...为了解决这个问题,我们要进行显式实例化 通常的实例化做法在所有需要得到模板声明的地方对模板声明注明extern的,这样编译器不会在这个模板实例化的时候生成代码而是去程序别处查找模板的实例 然后我们要保证这个...T&时,代表我们只能传递给他一个左值,此时如果传的T则得到类型T,如果传的const T则得到const T 当函数的参数const引用时,我们直到我们可以传递给他任何实参,此时const...,编译器也会从模板函数中实例化出可以调用的合适的函数 因此一般在编写重载函数的时候会编写多个比较特例的函数然后保留一个接受const T&的模板数来兜底防止失去匹配 在定义任何函数前异地你更要记得声明所有重载的函数版本防止编译器忽略你想要的版本而实例化了另一个...但如果只是部分特例化的模板则仍然模板,依然会参与匹配,部分特例化的版本的模板参数列表原始模板参数列表的一个子集或者一个特例化版本 通常为了正常的模板匹配我们都会在同一个头文件中写好所有同名模板声明

1.5K30
领券