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

【C++】泛型编程 ⑨ ( 类模板的运算符重载 - 函数声明 和 函数实现 写在同一个类中 | 类模板 的 外部友元函数问题 )

类模板 的 函数声明 与 函数实现 都写在同一个类中 ; 类模板 的 函数实现 在 类外部进行 , 写在相同的 .h 和 .cpp 源码文件中 ; 类模板 的 函数实现 在 类外部进行 , 写在不同的....h 和 .cpp 源码文件中 ; 2、代码示例 - 函数声明与函数实现分离 对于下面的 Father 类中的 printValue 函数 , // 声明 类模板 父类 template 类模板的运算符重载 - 函数声明 和 函数实现 写在同一个类中 1、类模板 的 外部友元函数问题 将上述 " 普通类的运算符重载 - 函数声明 和 函数实现 写在同一个类中 " 示例改造成 类模板...示例 ; 问题就出现在 定义在外部的 友元函数 中 , 友元函数 , 不能 读取 和 访问 到 泛型类型 T , 也就是 类模板 中 的 template 泛型类型 T ; 在外部重新定义...函数声明 和 函数实现 写在同一个类中 ( 包括友元函数 ) 代码示例 : #include "iostream" using namespace std; template <typename

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

    2W五千字的C++基础知识整理汇总

    基类 & 派生类 一个类可以派生自多个类,这意味着,它可以从多个基类继承数据和函数。定义一个派生类,我们使用一个类派生列表来指定基类。...因此基类成员如果不想被派生类的成员函数访问,则应在基类中声明为 private。...私有继承(private):当一个类派生自私有基类时,基类的公有和保护成员将成为派生类的私有成员。 多继承 多继承即一个子类可以有多个父类,它继承了多个父类的特性。...封装是面向对象编程中的把数据和操作数据的函数绑定在一起的一个概念,这样能避免受到外界的干扰和误用,从而确保了安全。数据封装引申出了另一个重要的 OOP 概念,即数据隐藏。...您可以使用模板来定义函数和类,接下来让我们一起来看看如何使用。

    2.6K10

    一文让你学完C++,干货收藏!!!

    基类 & 派生类 一个类可以派生自多个类,这意味着,它可以从多个基类继承数据和函数。定义一个派生类,我们使用一个类派生列表来指定基类。...因此基类成员如果不想被派生类的成员函数访问,则应在基类中声明为 private。...私有继承(private):当一个类派生自私有基类时,基类的公有和保护成员将成为派生类的私有成员。 多继承 多继承即一个子类可以有多个父类,它继承了多个父类的特性。...封装是面向对象编程中的把数据和操作数据的函数绑定在一起的一个概念,这样能避免受到外界的干扰和误用,从而确保了安全。数据封装引申出了另一个重要的 OOP 概念,即数据隐藏。...您可以使用模板来定义函数和类,接下来让我们一起来看看如何使用。

    3.4K20

    一文让你学完C++,干货收藏!!!

    基类 & 派生类 一个类可以派生自多个类,这意味着,它可以从多个基类继承数据和函数。定义一个派生类,我们使用一个类派生列表来指定基类。...因此基类成员如果不想被派生类的成员函数访问,则应在基类中声明为 private。...私有继承(private):当一个类派生自私有基类时,基类的公有和保护成员将成为派生类的私有成员。 多继承 多继承即一个子类可以有多个父类,它继承了多个父类的特性。...封装是面向对象编程中的把数据和操作数据的函数绑定在一起的一个概念,这样能避免受到外界的干扰和误用,从而确保了安全。数据封装引申出了另一个重要的 OOP 概念,即数据隐藏。...您可以使用模板来定义函数和类,接下来让我们一起来看看如何使用。

    3K3029

    一文让你学完C++,干货收藏!!!

    基类 & 派生类 一个类可以派生自多个类,这意味着,它可以从多个基类继承数据和函数。定义一个派生类,我们使用一个类派生列表来指定基类。...因此基类成员如果不想被派生类的成员函数访问,则应在基类中声明为 private。...私有继承(private):当一个类派生自私有基类时,基类的公有和保护成员将成为派生类的私有成员。 多继承 多继承即一个子类可以有多个父类,它继承了多个父类的特性。...封装是面向对象编程中的把数据和操作数据的函数绑定在一起的一个概念,这样能避免受到外界的干扰和误用,从而确保了安全。数据封装引申出了另一个重要的 OOP 概念,即数据隐藏。...您可以使用模板来定义函数和类,接下来让我们一起来看看如何使用。

    2.3K20

    C++为什么有参数依赖查找(ADL)?

    这个过程包括非限定名称查找和限定名称查找,以及在需要时的参数依赖查找和模板参数推导:非限定名称查找(Unqualified name lookup):当使用未限定的名称时(如std),编译器会在全局或命名空间作用域内查找该名称的声明...对于函数和函数模板名称,名称查找可以将多个声明与同一名称关联起来,并且可能从参数依赖查找中获得额外的声明(模板参数推导也可能适用),这一组声明集被传递给重载解析,来选择最终要使用的声明。...这种名称可以指向: 类成员(包括静态和非静态函数、类型、模板等) 命名空间成员(包括另一个命名空间) 通常在命名空间的作用域查找。...:首先会判断是否执行ADL:如果通常的未限定查找结果中包含类成员声明、块作用域中的函数声明(非using声明)或任何非函数或函数模板的声明,则不执行ADL。...为什么C++会有ADL为什么在限定名称查找和非限定名称查找之外,C++还要提供参数依赖查找这样的机制呢?

    12210

    C++基础知识精髓

    友元类: 友元类的所有成员函数都是另一个类的友元函数,都可以访问另一个类中的隐藏信息(包括私有成员和保护成员)。 当希望一个类可以存取另一个类的私有成员时,可以将该类声明为另一类的友元类。...2.只能出现在类定义内部,友元声明可以在类中的任何地方,一般放在类定义的开始或结尾。 3.友元可以是普通的非成员函数,或前面定义的其他类的成员函数,或整个类。...// 在多继承时,如果省略继承方式,默认为private // 如果在派生类中声明了一个与基类成员相同名字的函数,派生类的新成员会覆盖基类的同名成员 /* 不管何种继承 基类的私有程序都不能被派生类继承...模板定义以关键字template开始,后接模板形参表,模板形参表是用尖括号括住的一个或多个模板形参的列表,形参之间以逗号分开。...inline函数模板: 函数模板可以用与非模板函数一样的方式声明为inline。说明符放在模板形参表之后、返回类型之前,不能放在关键字template之前。

    2K50

    【笔记】《Effective C++》条款26-55

    error报错, 编译期的方法是额外分出细化的基类, 然后让特定的方法只在特定的基类中有对应的虚函数可重写(覆盖) 33 避免遮掩继承而来的名称 当一个名称同时在小作用域和大作用域中存在时, C++会进行遮掩...那么应该转用private继承防止误导用户 34 区分接口继承和实现继承 这部分是为了从语义上来理解C++的继承设计 成员函数的接口总是会被继承 纯虚函数: 仅接口, 意味着希望派生类自己进行实现 非纯虚函数...的双重意义 typename一般出现在模板参数中作为参数前缀, 在这种情况下typename和class是等价的(但是typename较晚推出, 建议使用语义更清晰的typename) 当一个模板中某个名称依赖于模板参数时...当这个名称还处于模板类中时, 称为嵌套从属名称(nested dependent names)...., 因此我们无法直接在模板类中调用模板化的基类的成员 有三种方法处理这个问题: 在调用基类函数前加上this指针this->foo();, 用指针进行多态调用 用using声明式using Base<Tmp

    93330

    【C++】自学终极笔记

    在上述示例中,首先给 name 设置了默认值,然后是 age。 默认参数只能在函数声明中出现一次: 默认参数只能在函数声明中出现一次,而不应该在函数定义中重复提供默认值。...Bat 中只包含一个共享的 Animal 子对象【来自于最远的、最顶层的虚拟基类】,避免了菱形继承问题。...这确保在使用基类指针指向派生类对象时,可以正确调用派生类的析构函数,避免内存泄漏。 纯虚函数: 纯虚函数本身在基类中没有具体的实现,而是在派生类中被强制要求实现。...这使得函数能够接受不同类型的参数,从而实现对多种数据类型的通用操作。函数模板使用 template 关键字声明,并且可以包含一个或多个类型参数。...类模板使用 template 关键字声明,并且可以包含一个或多个类型参数。

    24110

    《逆袭进大厂》第三弹之C++提高篇79问79答

    这就是纯虚函数的作用。  纯虚函数可以让类先具有一个操作名称,而没有操作内容,让派生类在继承时再去具体地给出定义。 凡是含有纯虚函数的类叫做抽象类。这种类不能声明对象,只是作为基类为派生类服务。...2) 多重继承的优点很明显,就是对象可以调用多个基类中的接口; 3) 如果派生类所继承的多个基类有相同的基类,而派生类对象需要调用这个祖先类的接口方法,就会容易出现二义性 4) 加上全局符确定调用哪一份拷贝...+如何处理多个异常的?...所以为了容易使用,几乎总是在头文件中放置全部的模板声明和定义。 140、在成员函数中调用delete this会出现什么问题?对象还可以使用吗?...空间浪费:因为每个可执行程序中对所有需要的目标文件都要有一份副本,所以如果多个程序对同一个 目标文件都有依赖,会出现同一个目标文件都在内存存在多个副本; 更新困难:每当库函数的代码修改了,这个时候就需要重新进行编译链接形成可执行程序

    2.2K30

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

    (friend T;) 函数声明的尾部加上final可以阻止后续派生类的覆盖, 函数声明的尾部加上override可以强制派生类进行覆盖 模板函数也可以有默认参数了, 且不一定要和模板类一样从右到左指定...)的访问, 从而在外部可以自动调用基类构造 C++11中继承构造函数和其他默认函数一样, 存在隐式声明的默认版本, 且如果不被使用就不会生成 继承构造函数的默认参数不会被继承, 反而会生成多个不同声明的构造函数的产生..., 所以当发生冲突的时候应该显式声明构造函数来因此冲突的函数 当派生类是虚继承了基类时, 不能使用继承构造函数 一旦使用了继承构造函数(用using Base::Base;)暴露出来, 自身的默认构造函数就和之前的隐藏规则一样...(为了保证成员摆放的顺序一致) 派生类有非静态成员时, 只有一个仅有静态成员的基类(为了保证基类能被直接折叠, 因为C没有继承关系) 基类有非静态成员时, 派生类没有非静态成员(为了派生类折叠, 因为C..., 这个union被称为变长成员 内联名字空间 namespace嵌套namespace后, 调用内部内容可能很繁琐 如果用using打开一些内层的空间又可能与模板编程冲突, 因为模板不允许不同名称空间的名字在模板中特化

    2K20

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

    using声明需要改变的名称(用::作用域符特指名称) 派生类对基类的转换也与派生列表的访问说明符有关,本质上与类型转换函数的权限有关 名称查找是根据编译时的目标的静态类型从内到外进行查找的,目标的静态类型决定了其是否可见...,对于实现的内容我们一样可以使用=default简化 如果基类中的基本操作函数不可访问或被删除,则派生类中的对应成员是被删除的因为我们无法使用基类来操作那些成员 C11中,我们可以用using重用基类定义的构造函数...,这些实参不会被继承,而是派生类会得到多个继承的构造函数,每个构造函数省略一个有默认实参的形参 当我们想要把继承体系的对象存放到容器中时,最好使用间接存储也就是存放基类指针(智能指针就更好了) 16...类模板不会推断参数的类型 类模板的成员函数只有在使用时才会实例化 类模板与另一个模板直接最常见的友元是一对一的友元,首先模板需要声明所有需要用到的名字,然后在声明友元时标注出目标类的具体模板实参 类模板也可以一对多友元...要注意如果声明了目标友元的模板实参标识符,这些标识符需要与自身类模板的标识符不同 我们不能用typedef来起模板的类型别名,但是C11让我们可以用using来起模板的类型别名 C11允许我们为函数模板和类模板提供默认参数

    1.7K10

    C++ 学习笔记

    9.2 模板和 inline 函数模板全特化后和普通函数相同,但函数模板一般定义在头文件中,为了避免在多个模块 include 时出现重复定义的错误,一般将全特化后的函数模板定义为 inline。...}; 十三、模板中的名称 13.1 名称分类 1.名称分为受限名称和非受限名称,受限名称前面有显式的出现 ->, ::, ....名称出现在一个模板中 b. 名称是受限的 c. 名称不是用于基类的派生列表或构造函数的初始化列表中 d. 名称依赖于模板参数 ADL 用于模板函数时,可能会产生错误。...2.非依赖型基类:无需知道模板名称就可以完全确定类型的基类。 3.非依赖型基类的派生类中查找一个非受限名称时,会先从非依赖型基类中查找,然后才是模板参数列表。...14.3 c++实例化模型 1.两阶段查找:编译器在模板解析阶段会检测不依赖于模板参数的非依懒型名称,在模板实例化阶段再检查依懒型名称。

    6.8K63

    《C++Primer》第十八章 用于大型程序的工具

    ,这些库会定义大量的全局名字,如类、函数和模板等,不可避免会出现某些名字相互冲突的情况。...声明可以出现在全局作用域、局部作用域、命名空间作用域以及类的作用域中;在类的作用域中,这样的声明语句只能指向基类成员(因为派生类只能为那些它可以访问的名字提供using声明) 2.3 using指示 using...当一个类具有多个基类时,有可能出现派生类从两个或者多个基类中继承了同名成员的情况。此时不加前缀限定符直接使用该名字将引发二义性。...要想避免潜在的二义性,最好的办法是在派生类中为该函数定义一个新版本。...虚继承 尽管在派生类列表中同一个基类只能出现一次,但实际上派生类可以多次继承同一个类: 派生类可以通过它的两个直接基类分别继承同一个间接基类 直接继承某个基类,然后通过另一个基类再一次间接继承该类 在默认情况下

    1.4K20

    《C++面向对象程序设计》✍千处细节、万字总结(建议收藏)「建议收藏」

    类声明中的关键字private、protected、public可以任意顺序出现。 若私有部分处于类的第一部分时,关键字private可以省略。...//声明类Y为类X的友元类 }; 当一个类被说明为另一个类的友元类时,它所有的成员函数都成为另一个类的友元函数,这就意味着作为友元类中的所有成员函数都可以访问另一个类中的所有成员。...在C++中,可以通过将这个公共的基类声明为虚基类来解决这个问题。这就要求从类base派生新类时,使用关键字virtual将base声明为虚基类。...: 妈妈喜欢月季 女儿喜欢百合 C++规定,如果在派生类中,没有用virtual显式地给出虚函数声明,这时系统就会遵循以下的规则来判断一个成员函数是不是虚函数:该函数与基类的虚函数是否有相同的名称、参数个数以及对应的参数类型...事实上,由于宏定义会造成不少麻烦,所以在C++中不主张使用宏定义。解决以上问题的另一个方法就是使用模板。

    3.4K40

    C++ 继承:代码传承的魔法棒,开启奇幻编程之旅

    一.继承的概念及定义 1.1继承的概念 继承是面向对象语言特性之一,它允许一个类(派生类)从另一个类(基类)中,继承其属性和方法。...这样做的好处是,提供了可以重用的代码,避免在写一个类时,它的一部分功能已经在另一个类中实现了,我们还需要在这个类中重新写一遍。...若没有显示写继承方式,class中默认的继承方式为private,在struct中默认的继承方式为public 1.3继承模板 继承模板允许一个模板继承另一个模板 需要注意的是继承基类后,基类还没有被实例化...指定基类类域,编译器才会进入基类中查早 没有被实例化的模板是无法寻找的,在编译后,编译器提示找不到print这个标识符,原因是基类是一个类模板,模板只是声明并没有被实例化,直接调用会报错。...如果没有在基类中实现默认构造,在派生类的构造函数的初始化列表阶段显示调用,需要将基类当为一个整体进行初始化 在初识化列表中初始化的顺序根据声明的前后顺序,基类最先出现,先初始化基类 基类没有提供构造

    11310

    深入理解面向对象编程特性 : 继承

    void foo() { Base::bar(); // 调用基类的bar函数 } }; 名称查找和依赖名称 名称查找与依赖名称的问题主要源于模板的按需实例化机制和两阶段名称查找机制...两阶段名称查找 C++编译器对模板代码进行两次名称查找: 第一次名称查找:在模板定义时进行。...编译器解析所有与模板参数无关的非依赖名称。 第二次名称查找:在模板实例化时进行。编译器解析依赖于模板参数的名称,即依赖名称。 依赖名称(Dependent Names)是指那些依赖于模板参数的名称。...但是由于foo()是依赖于模板参数T的成员函数,编译器无法确定foo()是从基类继承的。这是因为模板是按需实例化的,编译器在第一次查找时并不知道派生类实例化时会包含哪些基类成员。...继承与静态成员 在C++中,静态成员是属于类而不是某个特定对象的。⽗类定义了static静态成员,则整个继承体系⾥⾯只有⼀个这样的成员,这意味着即使类派生出了多个子类,它们都共享同一个静态成员实例。

    17910

    C++之面向对象的语法笔记

    异常捕获 类& 对象 C++类定义:本质上是定义一个数据类型的合集 类定义是以关键字 class 开头,后跟类的名称。...这个已有的类称为基类,新建的类称为派生类。 C++ 继承的继承指的就是基类和派生类的关系。...C++的多态性用一句话概括就是:在基类的函数前加上virtual关键字,在派生类中重写该函数,运行时将会根据对象的实际类型来调用相应的函数。...image.png 分类 虚函数 (c++多态的基础) 增加程序的扩展性 动态多态: 程序运行过程中,觉得哪一个函数被调用 静态多态: 重载(函数名称相同,参数不同,面向对象的特效,c 中不行)...模板类.png 类型转换 C++ 常见的几种类型转换 static_cast 普通值类型转换 const_cast 去常量 dynamic_cast 基类和派生类之间的转换 reinterpret_cast

    1.6K40

    【C++】基础:Effective C++高效编程建议

    理解 typename 的两个含义 43. 了解如何访问 templatized base classes(模板化基类)中的名字 44....将C++视为federation of languages(语言联合体) 最初的C++只是在C基础上增加了class(面向对象)的特性,而现在它已经成为融合多个子语言特性的联合体,即包括C、Object-Oriented...如果你提供一个成员 swap,请同时提供一个调用成员 swap 的非成员 swap。对于类(非模板),还要特化 std::swap。...最小化文件之间的编译依赖 最小化编译依赖后面的一般想法是用对声明的依赖取代对定义的依赖。基于此想法的两个方法是 Handle 类和 Interface 类。 库头文件应该以完整并且只有声明的形式存在。...理解 typename 的两个含义 43. 了解如何访问 templatized base classes(模板化基类)中的名字 44.

    23410
    领券