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

【C++】泛型编程 ⑩ ( 类模板的运算符重载 - 函数实现 写在类外部的同一个 cpp 代码中 | 类模板 的 外部友元函数二次编译问题 )

访问 构造函数 , 并实现该函数 , 使用域操作符 时 , 前面的类 需要指定 具体的泛型类型 , 这里使用 声明的 T 模板类型 作为 具体的 泛型类型 ; template T>...; 友元函数 中的 泛型类型 , 要当做 函数模板 对待 ; 模板函数就涉及到 二次编译 问题 , 下面先分析一下 模板函数 二次编译 导致的 类模板的友元函数 问题 ; 友元函数 不要乱用 , 只有在...重载 左移 右移 操作符时 , 才使用 友元函数 ; ( 1 ) 错误示例及分析 - 类模板 的 外部友元函数 二次编译 问题 在 类模板 内部声明 友元函数 , template <typename...( 2 ) 正确写法 友元函数 不要乱用 , 只有在 重载 左移 右移 操作符时 , 才使用 友元函数 ; 这是 函数模板 二次编译 问题 , 一般情况下 , 函数模板 只有在 调用时 , 才需要将...泛型类型 指明 , 在 函数名称后面 , 使用 注明泛型类型 , 但是在 类模板 声明 友元函数 时 , 就需要指定 泛型类型 ; 这样才能将 类模板中的 泛型 T , 与 友元函数在 外部实现时

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

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

    类模板 中进行运算符重载 , 就需要用到友元函数 ; 如果将 类模板 的 函数实现 , 定义在函数外部 , 结合 友元函数 使用 , 就变得很复杂 , 下面针对该问题进行讨论 ; 二、普通类的运算符重载..., 左移运算符 重载 是在类外部 通过友元函数实现的 , 因为左移运算符的 左操作数是 ostream& 类型的 , 如果定义在了 类内部 , 左操作数就默认为当前类 ; 代码示例 : #include...三、类模板的运算符重载 - 函数声明 和 函数实现 写在同一个类中 1、类模板 的 外部友元函数问题 将上述 " 普通类的运算符重载 - 函数声明 和 函数实现 写在同一个类中 " 示例改造成 类模板...示例 ; 问题就出现在 定义在外部的 友元函数 中 , 友元函数 , 不能 读取 和 访问 到 泛型类型 T , 也就是 类模板 中 的 template T> 泛型类型 T ; 在外部重新定义...template T> 就是重新定义了一个新的泛型 , 与 类模板 中的 T 不是同一个泛型类型 ; 解决上述问题 , 就需要将 友元函数 定义在 类模板 的内部 ; template

    27210

    【C++】泛型编程 ⑪ ( 类模板的运算符重载 - 函数实现 写在类外部的不同的 .h 头文件和 .cpp 代码中 )

    类模板的运算符重载 - 函数声明 和 函数实现 写在同一个类中 | 类模板 的 外部友元函数问题 ) 中实现了第一种情况 , 类模板 的 函数声明 与 函数实现 都写在同一个类中 , 也就是没有分开进行编码...; 在博客 【C++】泛型编程 ⑩ ( 类模板的运算符重载 - 函数实现 写在类外部的同一个 cpp 代码中 | 类模板 的 外部友元函数二次编译问题 ) 中 , 分析了 第二种情况 , 类模板 的...; 一、类模板的运算符重载 - 函数实现 写在类外部的不同的 .h 头文件和 .cpp 代码中 1、分离代码 后的 友元函数报错信息 - 错误示例 上一篇博客 【C++】泛型编程 ⑩ ( 类模板的运算符重载...- 函数实现 写在类外部的同一个 cpp 代码中 | 类模板 的 外部友元函数二次编译问题 ) 中 , 分析了 第二种情况 , 类模板 的 函数实现 在 类外部进行 , 写在 一个 cpp 源码文件中..." 这是 类模板 的实现机制 决定的 ; 还是 两次编译 造成的问题 ; 编译代码时 , 编译到 Student.h 时 , 会生成一个 类模板 函数头 , 编译 Student.cpp 时 , 类模板函数

    25310

    【C++】泛型编程 ⑬ ( 类模板示例 - 数组类模板 | 构造函数和析构函数 的 声明与实现 | 普通成员函数 的 声明与实现 | 外部友元函数 的 声明与实现 )

    ; 左移 重载 , 用于向 cout 中输出字符 , 打印数据到命令行 ; 需要使用 友元函数 在外部实现 ; 下标 [] 运算符重载 , 用于读取 数组中的数据 ; 等号 = 运算符重载...Array { public: // 数组下标 [] 操作符重载 // 数组元素类型是 T 类型 T& operator[](int i); } 普通成员函数 的 实现 : 类模板 外部 实现...ArrayT>::operator[](int i) { return m_space[i]; } 4、外部友元函数 的 声明与实现 重载 左移 操作符 , 由于 左移操作符的 做操作数是..., 类模板内部定义的 操作符重载函数 , 其 左操作数 必须是 类本身 ; 外部友元函数 的 声明 : 声明时 , 需要在 函数名 和 参数列表之间 注明 泛型类型 T>; 实现时 , 不能在 函数名...Array& a); } 外部友元函数 的 实现 : 在外部 实现 类模板的 友元函数 , 首先 , 还是注明 模板类型 , template T> ; 然后 , 在 函数参数 /

    52010

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

    友元分为:友元函数和友元类 通俗而言:友元函数的声明表达了友元函数能够访问这个类的权限,相当于客人(友元)函数拥有主人家的钥匙(友元声明),可以随便进出主人家里,偷吃主人家里的饼干(访问私有域成员...友元关系不能传递 (如果B是A的友元,C是B的友元,则不能说明C时A的友元) 友元关系不能继承(在继承板块有详细介绍) 代码演示: class Time { friend class Date...@ 重载操作符必须有一个类类型参数 用于内置类型的运算符,其含义不能改变:例如+ 作为类成员函数重载时,其形参看起来比操作数少一个(因为成员函数的第一个参数为隐藏的this) .* / :: /sizeof...通过实参a1将T推演为int,通过实参d1将T推演为double类型,但模板参数列表中只有一个T, 编译器无法确定此处到底该将T确定为int 或者 double类型而报错 解决方式: 用户自己强制类型转换...如果模板可以产生一个具有更好匹配的函数, 那么将选择模板 模板函数不允许自动类型转换,但普通函数可以进行自动类型转换 2.类模板 一.类模板的格式 templateT1, class T2

    25510

    C++中与类有关的注意事项(更新中~~~)

    如果一个类是另一个类的友元类,那么该类的友元函数将不能访问另一个类的私有成员。...在写类模板时,如何需要用到另一个类模板的私有成员,注意千万不要写成普通的友元形式,那样报错报到你哭,步骤自身感觉比较繁琐,见链接https://blog.csdn.net/lezardfu/article...关于运算符重载需要注意以下几点: 作为类成员的重载函数(以类名作为返回类型),其形参看起来比操作数少一个,因为隐式传递,限定为第一个操作数,举个例子,如下: T operator + (const Data...在使用类对象时显示的指定模板实参了,不要忘了,另外系统隐藏了一个 类对象,一般两个对象中隐藏第一个*/ 重载>> 和 时一般在public处声明(声明时不要忘记它是友元函数...重载类型转化操作符时应注意1.必须定义为类成员函数. 2.不能指定返回类型。

    71720

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

    设计良好的程序只有在强调速度时才在类实现的内部使用数组和指针。数组下标的正确类型是size_t。 预处理器变量NULL在编译时会被数值0替换。指针做减法操作得到的是ptrdiff_t类型。...友元:将非公有成员的访问权授予指定的类或函数。friend在类定义内部。友元引入的类名和函数(定义或声明)可以像预先声明的一样使用。...重载操作符:保留字operator后面接需要定义的操作符符号,返回类型和参数表和其它函数一样。只能重载已有的操作符,只针对类类型,最好重载原本对类类型无意义的操作符。...使用算法sort等时会假定一些操作符(类型定义重载操作符。重载操作符如果是成员函数,左操作数必须是该类的对象【一定是this】。 用函数或类操作某个类的数据可设置其为友元。...非类型形参的模板实参:template 实例化时必须是常量表达式 Screen 模板中的友元表示任何实例可以访问任何实例。模板类中可以有模板类成员。

    1.4K20

    运算符重载的基本规则和习惯用法是什

    运算符重载的通用语法 在重载时,你不能更改 C++ 中内置类型的运算符的含义,只能对自定义类型[1]的运算符进行重载。也就是,运算符两边的操作数至少有一个是自定义的类型。...., Nov, Dec} 你想为它重载递加和递减运算符,但是你是无法实现它们为成员函数的,因为在 C++ 中,枚举类型压根就没有成员函数这一说。...(译注:原回答并没有提及友元,不过我这里还是贴出它的友元实现。) class T { ......如果有getXXX()这一类的函数,那么设其为非成员函数就没什么问题;如果没有,设置为友元最佳,这样就可以直接访问私有成员。 || && 的用法和上面的一样,但是应用场景很难遇到需要重载这两个的。...但是我不推荐去重载它们,除非你有一些性能和内存的需求(译注:问题追踪也是一个需要用到重载的需求)。在一些高性能算法中,它们往往会对其重载以获得对内存的高利用。

    74510

    【C++】泛型编程 ⑭ ( 类模板示例 - 数组类模板 | 容器思想 | 自定义类可拷贝 - 深拷贝与浅拷贝 | 自定义类可打印 - 左移运算符重载 )

    一、容器思想 1、自定义类可拷贝 - 深拷贝与浅拷贝 上一篇博客 【C++】泛型编程 ⑬ ( 类模板示例 - 数组类模板 | 构造函数和析构函数 的 声明与实现 | 普通成员函数 的 声明与实现 | 外部友元函数...的问题 ; 下面的示例中 , 自定义类中的成员变量 char m_name[32] 是 在定义时 , 直接分配好的 , 如果 自定义类 中有 指针类型的成员变量 , 如 char* m_name , 涉及到...class Array { // 左移 操作符重载 // 注意 声明时 , 需要在 函数名 和 参数列表之间 注明 泛型类型 T> // 实现时 , 不能在 函数名 和 参数列表之间...// 数组元素类型是 T 类型 T& operator[](int i); // 等号 = 操作符重载 Array& operator=(const Array& a); private:..."Array.h" // 左移 操作符重载 // 注意 声明时 , 需要在 函数名 和 参数列表之间 注明 泛型类型 T> // 实现时 , 不能在 函数名 和 参数列表之间 注明 泛型类型

    20710

    C++重载操作符

    什么叫重载操作符?这要先说什么是操作符,其实最简单的:+、-、*、/、操作符,这些也是很常见的重载操作符。 那什么叫重载操作符?...那如果我把int类型的值放在第一个呢?类似这样: Time time3 = 1 + time1; 这会报错的,因为int类型并没有一个方法可以去调用Time类型参数的加法。...但是我们可以用友元函数来解决这个问题,关于友元函数是什么这里只简单介绍一下: 类的友元函数是非成员函数,因此不能用成员操作符来调用,在定义时也不需要使用::限定符,但它与成员函数的访问权限相同,也就是可以访问类的成员...我们用友元函数来实现int在前的加法: // 依然在类定义内,但因为不是成员函数,定义时不需要::限定符 // 原型: friend Time operator+(int h, const Time...是cout类型不能直接这么用,往往要写一长串成员变量来输出,但是我们重载一下就可以了,同样的,因为操作符的左边是cout而不是我们的类型对象,所以也要通过友元函数的方式来定义才能使用

    32720

    C++函数模板(模板函数)详解

    而这些 Swap 函数除了处理的数据类型不同外,形式上都是一样的。能否只写一遍 Swap 函数,就能用来交换各种类型的变量的值呢?继承和多态显然无法解决这个问题。因此,“模板”的概念就应运而生了。...,在一个cpp中 注意: 复制代码 //构造函数 没有问题 普通函数 没有问题 友元函数:用友元函数重载 > friend ostream& operator<< (ostream...&out, Complex &c3) ; 友元函数:友元函数不是实现函数重载(非 >) 1 需要在类前增加 类的前置声明 函数的前置声明 templateT> class...4 友元函数调用 必须写成 Complex c4 = mySub(c1, c2); cout<<c4; 结论:友元函数只用来进行 左移 友移操作符重载。...,在不同的.h和.cpp中 也就是类模板函数说明和类模板实现分开 //类模板函数 构造函数 普通成员函数 友元函数 用友元函数重载>; 用友元函数重载非> demo_complex.cpp

    1.8K40

    C++primer学习笔记(六)

    派生类继承基类的访问控制标号【何种方式继承】无论是什么,不影响派生类使用基类成员,但影响使用派生类的用户访问基类成员。类使用接口继承还是实现继承对派生类用户具有重要含义。 友元关系不继承。...派生类指针的静态类型和动态类型不一致时【基类指针指向派生类是时】,为保证删除指针调用合适的析构函数【多态】,基类析构必须为virtual。...构造函数是对象动态类型确定之前运行的,不需要定义为virtual。 引用、对象、指针的静态类型决定了能够完成的行为,动态类型有多的功能也无法使用。派生类应避免与基类成员名字冲突。...局部作用域中声明的函数不会重载全局域的函数。派生类定义的函数也不重载基类函数【想重载要么不定义,要么全定义】。using作用域。...非类型形参的模板实参:template 实例化时必须是常量表达式 Screen 模板中的友元表示任何实例可以访问任何实例。模板类中可以有模板类成员。

    1.1K20

    C++复习篇

    种转换 9.拷贝构造函数 10.构造函数初始化列表 11.析构函数 12.const成员函数 13.const对象 14.栈、堆、静态存储区的区别 15.静态成员变量/静态成员函数 16.友元friend...,打印: mval=4 } 16.友元friend 友元的好处在于,方便快捷.可以通过friend函数来访问这个类的私有成员 友元的坏处在于,破坏了面向对象的封装性,在现代已经逐渐被遗弃 示例: #include...; //声明Test的友元是f_func()函数 }; int Test::n = 3; void f_func(const Test& t) {   printf("t.x=%d\n",t.x...  f_func(t1);   return 0; }  17.operator操作符重载函数 使'+,-,*,/'等操作符拥有了重载能力,能够实现对象之间的操作,而不再单纯的普通变量之间的操作了....18.通过()操作符重载实现:函数对象 函数对象是指该对象具备函数的行为 函数对象,是通过()调用操作符声明得到的,然后便能通过函数方式来调用该对象了. ()调用操作符可以定义不同参数的多个重载函数 (

    1.3K20

    C++泛型编程,模板(二)类模板

    ,可以有三种方式向函数中进行传参 使用比较广泛是第一种:指定传入的类型 类模板与继承 当类模板碰到继承时,需要注意一下几点: 当子类继承的父类是一个类模板时,子类在声明的时候,要指定出父类中T的类型 如果不指定...,需要加上模板参数列表 类模板分文件编写 学习目标: 掌握类模板成员函数分文件编写产生的问题以及解决方式 问题: 类模板中成员函数创建时机是在调用阶段,导致分文件编写时链接不到 解决: 解决方式1:直接包含...,将类模板成员函数写到一起,并将后缀名改为.hpp 类模板与友元 学习目标: 掌握类模板配合友元函数的类内和类外实现 全局函数类内实现 - 直接在类内声明友元即可 全局函数类外实现 - 需要提前让编译器知道全局函数的存在...示例: #include //2、全局函数配合友元 类外实现 - 先做函数模板声明,下方在做函数模板定义,在做友元 templateT1, class T2> class...构造 而是赋值, // 普通类型可以直接= 但是指针类型需要深拷贝 this->pAddress[i] = arr.pAddress[i]; } } //重载= 操作符 防止浅拷贝问题

    1.3K30

    【C++】泛型编程 ⑫ ( 类模板 static 关键字 | 类模板 static 静态成员 | 类模板使用流程 )

    类模板的运算符重载 - 函数声明 和 函数实现 写在同一个类中 | 类模板 的 外部友元函数问题 ) 中实现了第一种情况 , 类模板 的 函数声明 与 函数实现 都写在同一个类中 , 也就是没有分开进行编码...; 在博客 【C++】泛型编程 ⑩ ( 类模板的运算符重载 - 函数实现 写在类外部的同一个 cpp 代码中 | 类模板 的 外部友元函数二次编译问题 ) 中 , 分析了 第二种情况 , 类模板 的...T> , 其中的 T 类型可以改为其它字母代替 , 一般是大写字母 ; 2、类模板 使用 使用类模板 : 使用 类模板 创建实例对象时 , 首先要注明 具体类型 , 生成具体类 , 才能创建具体类的...声明 类模板 的类型参数 ; template 类型参数列表> 然后 , 使用 域操作符 :: 访问类模板中的函数 , 访问时需要 注明 类模板的 实际参数类型 ; 函数返回值类型...Student& s); }; 在 类模板 外部 实现上述 函数声明 , 就需要使用如下方式 ; // 重载 + 运算符 // 使用 StudentT>:: 域操作符访问函数 template <typename

    26610

    C++面向对象程序设计_Part1

    函数重载 构造函数的位置 参数传递 返回值传递 友元 操作符重载(一),this, cout 操作符重载(二)非成员函数,无this,临时对象 Big Three ---string class begin...private中主要防止类的数据,目的就是要隐藏数据,只暴露public中的接口,private中有double类型的实虚部,以及一个友元函数,这个友元函数实现的是复数的相加,将用于public中的+=...操作符重载中,在public中,有四个函数,第一个是构造函数,目的是初始化复数,实虚部默认值为0,当传入实虚部时,后面的列表初始化会对private中的数据进行初始化,非常推荐使用列表初始化数据。...模板可以只写一份模板代码,需要生成不同类型的class,编译器会自动生成,具体做法是在类定义最上方加入template ,然后讲所有的double都换成T即可,在初始化的时候,在类的后面使用尖括号,尖括号中放入你想要生成的类型即可...(引用本质上就是指针,主要用在参数传递和返回值传递) 友元 ? 友元函数是类的朋友,被设定为友元的函数可以访问朋友的私有成员,这个函数(do assignment plus)用来做复数加法的具体实现。

    97420

    C++初阶

    函数原型:返回值类型operator操作符(参数列表) 注意: 不能通过连接其他符号来创建新的操作符:比如operator@ 重载操作符必须有一个类类型参数 用于内置类型的运算符,其含义不能改变,例如:...不过可以强转直接赋空,不过一般不进行这样的操作 13.友元函数和友元类(Date里有) 问题:现在尝试去重载operator,然后发现没办法将operator重载成成员函数。...,但不是类的成员函数 友元函数不能用const修饰 友元函数可以在类定义的任何地方声明,不受类访问限定符限制 一个函数可以是多个类的友元函数 友元函数的调用与普通函数的调用原理相同 友元类 友元类的所有成员函数都可以是另一个类的友元函数...友元关系不能传递 如果B是A的友元,C是B的友元,则不能说明C时A的友元。...通过实参a1将T推演为int,通过实参d1将T推演为double类型,但模板参数列表中只有一个T, 编译器无法确定此处到底该将T确定为int 或者 double类型而报错 注意:在模板中

    10210

    C++初阶大全

    函数原型:返回值类型operator操作符(参数列表) 注意: 不能通过连接其他符号来创建新的操作符:比如operator@ 重载操作符必须有一个类类型参数 用于内置类型的运算符,其含义不能改变,例如:...不过可以强转直接赋空,不过一般不进行这样的操作 13.友元函数和友元类(Date里有) 问题:现在尝试去重载operator,然后发现没办法将operator重载成成员函数。...,但不是类的成员函数 友元函数不能用const修饰 友元函数可以在类定义的任何地方声明,不受类访问限定符限制 一个函数可以是多个类的友元函数 友元函数的调用与普通函数的调用原理相同 友元类 友元类的所有成员函数都可以是另一个类的友元函数...友元关系不能传递 如果B是A的友元,C是B的友元,则不能说明C时A的友元。...通过实参a1将T推演为int,通过实参d1将T推演为double类型,但模板参数列表中只有一个T, 编译器无法确定此处到底该将T确定为int 或者 double类型而报错 注意:在模板中

    5810

    【C++初阶】C++入门

    19、friend 友元。使其不受访问权限控制的限制。例如,在1个类中,私有变量外部是不能直接访问的。...可是假如另外1个类或函数要访问本类的1个私有变量时,可以把这个函数或类声明为本类的友元函数或友元类。这样他们就可以直接访问本类的私有变量。...public为公有的,访问不受限制;protected为保护的,只能在本类和友元中访问;private为私有的,只能在本类、派生类和友元中访问。...32、virtual 声明虚基类,虚函数。虚函数=0时,则为纯虚函数,纯虚函数所在的类称为抽象类。 33、typeid typeid是一个操作符,返回结果为标准库种类型的引用。...函数重载概念:   函数重载:是函数的一种特殊情况,C++允许在同一作用域中声明几个功能类似的同名函数,这些同名函数的形参列表(参数个数 或 类型 或 顺序)必须不同,常用来处理实现功能类似数据类型不同的问题

    1.3K30
    领券