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

【笔记】《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.2K20

    【C++】模版进阶

    一、非类型模版参数 模版参数分为类型形参与非类型形参 类型形参:出现在模版参数列表中,跟在class或者typename之类的参数类型名称 非类型形参:用一个常量作为类模板的一个参数,在类模板中可将该参数当成常量来使用...非类型的模版参数必须在编译期就能确认结果 这里就是允许给类模板定义常量参数,可以在类模板中使用 二、模版的特化 1、概念 通常情况下,使用模版可以实现一些与类型无关的代码,但对于一些特殊类型的可能会得到一些错误的结果...,导致链接时找不到地址而报错 解决办法就是声明和定义都在一个.h文件当中,这也是最好的一种方式 四、对于模版的总结 优点:模版复用了代码,节省资源,更快的迭代开发,C++的STL也因此产生 增强了代码的灵活性...class而必须使用typename的 1、依赖类型 当模板类型参数用于指定另一个类型的成员类型时,如果这种类型关系依赖于模板参数,则必须使用typename来指明这是一个类型,这是因为编译器在解析模板时可能无法立即确定某个名字是指代类型还是非类型...>::const_iterator ,就无法知道list::const_iterator是内嵌类型还是静态成员变量,前面加一个typename就是告诉编译器,这里是一个类型,等list< T

    7810

    C++模板初阶

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

    62700

    【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; 注意区分: 在类中:类名等同于类型 在类模板中:类型是类型,类名是类名 例如:在下面代码中,类模板中函数放在类外进行定义时,

    25910

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

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

    17000

    【C++】C++入门知识详解(下)

    1.缺省值和缺省参数 缺省参数就是声明或定义函数时为函数的参数指定一个缺省参数。在调用该函数时,如果没有指定实参,则采用该形参的缺省值,否则,使用指定的参数。 有些地方把缺省参数也叫做默认参数。...2.1 参数类型不同 同样是实现两个数的相加,一个是整数的相加,一个是小数的相加,在C语言中我们可能就会分成两个不同的函数来实现,比如add1实现整数的相加,add2实现小数的相加,有了函数重载,我们就可以用...其实,在函数调用时,会根据我们传给函数的实参的类型自动调用相应的函数。...int a = 0; int& b = a; //给a取别名为b int& c = a; //给a再取一个别名为c 我们可以不止取一个别名,一个变量可以有多个别名。我们还可以给别名取别名,如下。...1.函数传参其实是把实参拷贝给形参,形参是实参的临时拷贝,有了引用就可以减少拷贝。 2.引用从语法上来说,形参是实参的别名,形参也不会额外开辟空间,效率就得到了提高。

    9610

    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...原因分析 类模板分离编译会报链接错误 一般建议类模板在同一个文件中声明和定义分离,这是最好的方式了,达到了类中简洁只有函数声明,同时没有各种错误; 来看看类声明和定义分离且不在一个文件会遇到的问题

    81720

    【笔记】C++2.0新特性

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

    91520

    【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 不能用于模板参数的类型声明 ⭐类成员变量 类成员变量的类型是在类定义时确定的,编译器无法在编译时推导出类成员变量的类型

    25410

    C++基础知识概述

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

    99720

    【C++】初识模板

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

    54730

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

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

    2K20

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

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

    2.3K20

    C++11 变参模板

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

    3.4K51

    【C++】模板进阶

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

    1.1K20

    第6章 函数

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

    1.3K70

    【C++】模板进阶

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

    21130

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

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

    27510
    领券