类模板是创建类的模式

news/2024/9/24 12:19:04/
  1. 类模板和函数模板一样,使用关键字template引入一个类模板。类模板是创建类的模式,通过提供模板参数来实现,例如Point<int>

  2. 类模板的成员函数本身就是函数模板,使用相同的模板参数,只是将模板参数提供给类,而不是函数,就像在下面示例中函数Point<T>::moveTo实现的那样。

  3. 每当使用不同的模板参数时,编译器就会生成一个新的类实例,具有新的成员函数。
    也就是说,Point<int>::moveTo是一个函数,Point<double>::moveTo是另一个函数,这正是手动编写这些函数会发生的情况。如果两个不同的源文件都使用Point<int>,编译器和链接器会确保它们共享同一个模板实例。

  4. 也正因为如此不能把一个Point<int>对象赋给一个Point<float>对象,详见下面代码中注释掉的pt3 = pt2后面的报错信息。

  5. 下面代码也给出了类内又有模板的实现方式。

#include <iostream>
#include <vector>template<class T>
class Point{
public:Point(T x, T y):x_(x), y_(y){std::cout << __PRETTY_FUNCTION__ << std::endl;}Point(const Point& pt): x_(pt.x_), y_(pt.y_){std::cout << __PRETTY_FUNCTION__ << std::endl;}Point& operator=(const Point& pt)& {Point(pt.x_, pt.y_).swap(static_cast<Point&>(*this));std::cout << __PRETTY_FUNCTION__ << std::endl;return *this;}Point(Point&& pt) noexcept: x_(pt.x_), y_(pt.y_) {std::cout << __PRETTY_FUNCTION__ << std::endl;}Point& operator=(Point&& pt)& noexcept{x_ = pt.x_;y_ = pt.y_;std::cout << __PRETTY_FUNCTION__ << std::endl;return *this;}void swap(Point& pt) noexcept{std::swap(x_, pt.x_);std::swap(y_, pt.y_);std::cout << __PRETTY_FUNCTION__ << std::endl;}virtual ~Point(){std::cout << __PRETTY_FUNCTION__ << std::endl;}T getX()const{return x_;}T getY()const{return y_;}void moveTo(T x, T y);/*【类内又有模板】方式一,在类内声明,在类外定义 */template<class U>U ratio() ;/*【类内又有模板】方式二,在类内定义 */template<class V>V multiply() {return static_cast<V>(x_) * static_cast<V>(y_);}private:T x_;T y_;
};template<class T>
void Point<T>::moveTo(T x, T y){x_ = x;y_ = y;
}template<class T>
template<class U>
U Point<T>::ratio() {return static_cast<U>(x_) / static_cast<U>(y_); // omit devided by zero.
}int main() {Point<int> pt1(1, 2);Point<float> pt2(3.4, 5.6);Point<int> pt3(pt1);pt3 = pt1;//pt3 = pt2;  // error: no match for 'operator=' (operand types are 'Point<int>' and 'Point<float>')std::cout << "x = "<< pt3.getX() << ", y = " << pt3.getY() << std::endl;  // x = 1, y = 2】pt3.moveTo(5, 6);std::cout << "x = "<< pt3.getX() << ", y = " << pt3.getY() << std::endl;  // x = 5, y = 6std::cout << pt3.ratio<float>() << std::endl;     // 0.833333std::cout << pt3.multiply<float>() << std::endl;  // 30
}

http://www.ppmy.cn/news/1456362.html

相关文章

【网络知识】光猫、路由器 和 交换机 的作用和区别?

数字信号&#xff1a;是指自变量是离散的、因变量也是离散的信号&#xff0c;这种信号的自变量用整数表示&#xff0c;因变量用有限数字中的一个数字来表示。在计算机中&#xff0c;数字信号的大小常用有限位的二进制数表示。 模拟信号&#xff1a;模拟信号是指用连续变化的物…

2024-3-23 青少年软件编程(C语言)等考(三级)解析

2024-3-23 青少年软件编程(C语言)等级考试试卷(三级)解析1、我家的门牌号 我家住在一条短胡同里,这条胡同的门牌号从1开始顺序编号。 若所有的门牌号之和减去我家门牌号的两倍,恰好等于n,求我家的门牌号及总共有多少家。 数据保证有唯一解。 时间限制:1000 内存限制:6…

(双指针)移动零 复写零 快乐数 盛水最多的容器

提示&#xff1a;文章写完后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 目录 文章目录 前言 一、移动零 1.1、题目 1.2、讲解算法原理 1.3、编写代码 二、复写零 2.1、题目 2.2、讲解算法原理 2.3、编写代码 三、快乐数 3.1、题目 3.…

【Linux进程】信号

目录 入门 前&后台进程 前台进程&#xff1a; 后台进程 常用命令 ./XXX & fg命令 & bg命令 Ctrl c / Ctrl \ 信号的概念 信号的产生 1.键盘产生 2.系统调用指令 3.异常 4.软件条件 信号的保存 信号的处理 1.信号屏蔽字 2.未决信号表 3.信号处理…

VUE----数字增加,兼容小程序

数字增加&#xff0c;兼容小程序 requestAnimationFrame 为浏览器提供的方法 export function countUp(duration, from, to, onProgress) {let value fromconst speed (to - from) / durationconst start Date.now()if (typeof window undefined) {let requestAnimationF…

头歌实践教学平台:CG2-v2.0-三角形填充

第1关&#xff1a;扫描线填充法 一. 任务描述 1. 本关任务 了解和掌握扫描线填充法&#xff0c;实现对三角形区域进行填充&#xff0c;具体要求如下&#xff1a; (1) 补全triangle函数; (2) 将main函数中的三角形顶点坐标和triangle函数参数补充完整。 2. 输入 (1) 三角形…

DDR5内存新标准问世,体验前所未有的数据传输速度

DDR 5&#xff0c;新标准发布 JEDEC 发布了 JESD79-5C DDR5 SDRAM 标准&#xff0c;带来了关键更新&#xff0c;包括&#xff1a;* 增强可靠性和安全性* 优化高性能服务器和新兴技术&#xff08;如 AI 和机器学习&#xff09;的性能* 标准可从 JEDEC 网站下载 JESD79-5C 引入每…

视频剪辑神器:批量高效处理,轻松锐化视频让影片焕然一新!

视频已经成为我们记录生活、分享故事、展示才华的重要形式。然而&#xff0c;面对大量的视频文件&#xff0c;如何批量高效剪辑并提升视频质量&#xff0c;成为了许多人的难题。现在&#xff0c;我们为您带来一款视频剪辑神器&#xff0c;让您轻松处理视频&#xff0c;让您的影…