类模板的常见用法

这篇具有很好参考价值的文章主要介绍了类模板的常见用法。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

class_template

类模板和函数模板的定义和使用类似,我们已经进行了介绍。有时,有两个或多个类,其功能是相同的,仅仅是数据类型不同。类模板用于实现类所需数据的类型参数化

template<class NameType, class AgeType>
class Person
{
public:
	Person(NameType name, AgeType age)
	{
		this->mName = name;
		this->mAge = age;
	}
	void showPerson()
	{
		cout << "name: " << this->mName << " age: " << this->mAge << endl;
	}
public:
	NameType mName;
	AgeType mAge;
};
void test1() {
	Person<string, int>p1("regina", 23);
	p1.showPerson();
	Person<char, float>p2('i', 23.1);
	p2.showPerson();
}

类模板的常见用法

类模板做函数参数

void param(Person<string, int>& p) {
	p.mAge += 10;
	p.mName += "regina";
	p.showPerson();
}
int main() {
	Person<string, int> p("love", 20);
	param(p);
	return 0;
}

类模板的常见用法

类模板派生普通类

template<class NameType, class AgeType>
class Person
{
public:
	Person(NameType name, AgeType age)
	{
		this->mName = name;
		this->mAge = age;
	}
	void showPerson()
	{
		cout << "name: " << this->mName << " age: " << this->mAge << endl;
	}
public:
	NameType mName;
	AgeType mAge;
};
class Subclass : public Person<string, int> {
public:
	Subclass(string name, int age):Person<string, int>(name,age) {
		this->mName = name;
		this->mAge = age;
	}
};

int main() {
	Subclass p("regina", 17);
	p.showPerson();
	return 0;
}

Subclass(string name, int age):Person<string, int>(name,age)这句话首先声明带参数的构造函数里面的类型。这个类型要和后面使用类模板的父类的构造函数参数类型一样。但是当你在定义一个类时,如果该类是模板类的实例化,你可以直接使用类名而不需要指定模板参数,因为编译器可以根据构造函数参数的类型来推断模板参数的类型

类模板派生类模板

派生类不仅继承了基类的成员和行为,还继承了基类的模板参数,并可以在派生类中添加额外的模板参数或覆盖基类模板参数。这样可以使得派生类在使用时更加灵活,并且可以根据需要进行定制化。

template<class MoneyType>
class Subclass : public Person<string, int> {
public:
	Subclass(string name, int age, MoneyType have_money):Person<string, int>(name,age), havemoney(have_money) { /*这里的继承就是多一个对于自己的模板的默认构造函数的声明*/
		this->mName = name;
		this->mAge = age;
	}
	void showPerson() {
		Person<string,int>::showPerson();
		cout << "have_money: " << (havemoney ? "true" : "false") << endl;
	}
private:
	MoneyType havemoney;
};
int main() {
	Subclass<bool> p("regina", 17,true);
    /*在 main 函数中只传递了一个 bool 类型的参数,因为 Subclass 类模板只接受一个模板参数 MoneyType*/
	p.showPerson();
	return 0;
}

类模板的常见用法

类模板类内实现和类外实现

类模板类内实现指的是在类模板的定义中直接实现成员函数的方法。与普通类相似,类模板也可以在类内部实现成员函数,这意味着成员函数的定义可以直接放在类模板的声明中,而不需要在类外部再单独定义。这种方式使得代码更加简洁,并且可以避免在类外部定义时重复书写模板的参数列表。


template<class NameType, class AgeType>
class Person
{
public:
	Person(NameType name, AgeType age);
	void showPerson();
public:
	NameType mName;
	AgeType mAge;
};
template<class NameType, class AgeType>
Person<NameType, AgeType>::Person(NameType name, AgeType age) {
	this->mName = name;
	this->mAge = age;
}
template<class NameType, class AgeType>
void Person<NameType, AgeType>::showPerson() {
	cout << "Name:" << this->mName << " Age:" << this->mAge << endl;
}

template<class NameType, class AgeType>这个一共声明了三次是为什么呢?

  1. 模板类声明: 在C++中,模板类的成员函数可以直接在类的定义中进行声明和实现,但也可以在类定义之外单独实现。在类定义之外实现时,必须再次使用 template<class NameType, class AgeType> 来指明这是一个模板类的成员函数。
    • 在类定义中进行声明的情况下,模板参数已经被识别,所以无需再次声明。
  2. 类定义外的实现: 如果你在模板类的定义之外实现成员函数,则需要重新指明该成员函数属于特定的模板类。这是因为C++编译器在进行模板解析时需要知道这些函数与哪个模板类相关联。

类模板头文件和源文件分离问题

类模板的头文件和源文件分离是指将类模板的声明和定义分别放置在不同的文件中的做法。通常,类模板的声明(包括模板类的成员函数声明)放在头文件(通常是 .hpp.h 文件),而类模板的实现(包括成员函数的定义)则放在源文件(通常是 .cpp 文件)中。

这种分离的做法有几个好处:

  1. 模块化: 将类模板的声明和定义分开可以更好地组织代码,使得代码结构更清晰,易于维护和理解。
  2. 编译时间: 如果类模板的实现放在源文件中,在使用该类模板的地方只需要包含头文件即可,这样可以减少编译时间,因为编译器只需要编译一次模板的实现,而不是每次包含头文件时都重新编译一次。
  3. 隐藏实现细节: 将类模板的实现放在源文件中可以隐藏模板的具体实现细节,只向用户暴露接口,提高了代码的封装性和安全性。
#pragma once
/*是一种预处理器指令,用于确保在编译过程中头文件只被包含一次,以避免多重包含问题。

当编译器遇到 #pragma once 时,它会在编译过程中记住这个头文件的路径和文件名,
并在后续的 #include 指令中检查是否已经包含了相同的文件。如果已经包含过了,
那么该头文件将被忽略,不会再次包含。这样可以防止由于多重包含而导致的编译错误
或者重复定义的问题。

使用 #pragma once 可以简化头文件的管理,使得头文件的包含更加简洁和高效。*/

template<class T1, class T2>
class Person {
public:
	Person(T1 name, T2 age);
	void ShowPerson();
public:
	T1 mName;
	T2 mAge;
};

template<class T1, class T2>
Person<T1, T2>::Person(T1 name, T2 age) {
	this->mName = name;
	this->mAge = age;
}

template<class T1, class T2>
void Person<T1, T2>::ShowPerson() {
	cout << "Name:" << this->mName << " Age:" << this->mAge << endl;
}

模板类碰到友元函数

template<class T1, class T2> class Person;
template<class T1, class T2> void PrintPerson2(Person<T1, T2>& p);

template<class T1, class T2>
class Person {
	//1. 友元函数在类内实现
	friend void PrintPerson(Person<T1, T2>& p) {
		cout << "Name:" << p.mName << " Age:" << p.mAge << endl;
	}
	//2.友元函数类外实现
	//告诉编译器这个函数模板是存在
	friend void PrintPerson2<>(Person<T1, T2>& p);//<> 是用来指示编译器,PrintPerson2 是一个函数模板的声明

	//3. 类模板碰到友元函数模板
	template<class U1, class U2>
	friend void PrintPerson(Person<U1, U2>& p);
public:
	Person(T1 name, T2 age) {
		this->mName = name;
		this->mAge = age;
	}
	void showPerson() {
		cout << "Name:" << this->mName << " Age:" << this->mAge << endl;
	}
private:
	T1 mName;
	T2 mAge;

};
template<class T1, class T2>
void PrintPerson2(Person<T1, T2>& p)
{
	cout << "Name2:" << p.mName << " Age2:" << p.mAge << endl;
}
void test1() {
	Person<string, int> p("regina", 25);
	PrintPerson(p);
	PrintPerson2(p);
}

以下是为什么需要在类外部声明友元模板函数的原因:文章来源地址https://www.toymoban.com/news/detail-858101.html

  1. 预声明模板函数:当你在类内使用 friend 关键字声明一个友元模板函数时,你实际上告诉编译器这个函数会访问类的私有成员。但是这并不等同于定义了这个模板函数。因此,你仍然需要在类外部定义并实现这个模板函数。如果没有外部的声明和实现,编译器将无法找到这个函数模板,导致链接错误。
  2. 函数模板的明确声明:在使用友元模板函数时,编译器需要明确知道它是一个模板函数,并且知道它如何被实例化。如果你不在类外部声明这个函数模板,编译器可能不会正确处理其实例化,导致意外的编译错误。
  3. 类内部声明只是告诉编译器:在类内部通过 friend 声明友元模板函数只是告诉编译器该模板函数能够访问类的私有成员,并没有定义该函数的具体实现。因此,必须在类外部提供该函数模板的声明和实现,以确保编译器知道它的具体实现位置。

到了这里,关于类模板的常见用法的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • Template Pattern —— Behavioral Class

    钩子方法(Hook Method)之所以被称为“钩子”,是因为它在算法或流程中提供了一个“钩子”,允许子类在特定的点上“钩入”自己的实现逻辑,从而影响算法的行为或流程的执行。 它类似于一个挂钩、锚点,所以叫Hook method, 它允许子类插入自定义的代码来改变或扩展算法的

    2024年02月10日
    浏览(36)
  • hiveSQL常见函数及用法(持续收集)

    注意:聚合函数常与 SELECT 语句的 GROUP BY 子句一块儿使用。换句话说使用聚合函数时,一个列字段要不在group by里,要没必要须在聚合函数里面,不能单独出现,不然报错。 1,lead(col,n,m) over(partition by … order by …) : 其中col是要取的字段,n是取排序后的第几条记录;m是缺省

    2024年02月03日
    浏览(32)
  • C++11可变参数模板(typename... Args模板参数包或class... Args)(Args... args函数参数包)(递归展开与参数包展开(只支持C++17))

    C++可变参数是指函数的参数个数是可变的,可以在函数定义时不确定参数的个数,需要在函数体内通过特定的语法来处理这些参数。C++11标准引入了新的可变参数模板,使得可变参数的处理更加方便和灵活。在函数定义时,可以使用省略号(…)来表示可变参数,然后通过va_li

    2024年02月08日
    浏览(42)
  • 常见的四种排名函数的用法(sql)

    四个排名函数: 1.row_number 2.rank 3.dense_rank 4.ntile 1. ROW_NUMBER(排名场景推荐) 1.1 介绍 在 SQL 中,ROW_NUMBER() 是一个窗口函数,它为结果集中的每一行分配一个唯一的序号。该函数的语法如下: 其中,ORDER BY 子句指定了 ROW_NUMBER() 函数排列行的顺序。如果省略 ORDER BY,则序号将按

    2024年02月01日
    浏览(35)
  • 【Wordpress高级教程】WordPress模板基本文件和常见函数调用代码

    WordPress是使用PHP语言开发的博客平台,用户可以在支持PHP和MySQL数据库的服务器上架设属于自己的网站。也可以把 WordPress当作一个内容管理系统(CMS)来使用。 WordPress有许多第三方开发的免费模板,安装方式简单易用。用户可以在支持 PHP 和 MySQL数据库的服务器上快速搭建自

    2024年02月02日
    浏览(37)
  • An error happened during template parsing (template: "class path resource [templates/user.html]")问题解...

    问题: An error happened during template parsing (template: \\\"class path resource [templates/user.html]\\\")  解决方法: 1.配置文件问题。根据问题描述,问题可能为想要去的地址路径错误。解决方法:修改路径。    2.@RestController @RestController相当于@Response + @Controller,作用是将return的字符串响应在界

    2024年02月16日
    浏览(33)
  • 浅谈WPF之控件模板Control Template和数据模板Data Template

    WPF不仅支持传统的Windows Forms编程的用户界面和用户体验设计,同时还推出了以模板为核心的新一代设计理念。在WPF中,通过引入模板,将数据和算法的“内容”和“形式”进行解耦。模板主要分为两大类:数据模板【Data Template】和控件模板【Control Template】 基本上,ControlT

    2024年02月03日
    浏览(34)
  • (二)模板templates

    Django模板层是为动态生成html服务的,非本文重点。前后端分离的设计更为常见,尽量少的涉及Django模板层内容。本文记录Django如何找到一个html文件。 在创建一个Django项目project后,目录下会生成一个同名目录和manage.py。创建一个app,并为app编写一个视图,如: 当通过路由访

    2024年01月16日
    浏览(31)
  • [C++] 模板template

      目录 1、函数模板 1.1 函数模板概念 1.2 函数模板格式 1.3 函数模板的原理 1.4 函数模板的实例化 1.4.1 隐式实例化 1.4.2 显式实例化 1.5 模板参数的匹配原则 2、类模板 2.1 类模板的定义格式 2.2 类模板的实例化 讲模板之前呢,我们先来谈谈泛型编程: 泛型编程:编写与类型无关

    2024年02月13日
    浏览(68)
  • 【C++】模板template

           🔥🔥 欢迎来到小林的博客!!       🛰️博客主页:✈️林 子       🛰️博客专栏:✈️ C++       🛰️社区 :✈️ 进步学堂       🛰️欢迎关注:👍点赞🙌收藏✍️留言 模板是C++中泛型编程的基础,一个模板就是一个创建

    2024年02月12日
    浏览(92)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包