C++之类模板

追求适度,才能走向成功;人在顶峰,迈步就是下坡;身在低谷,抬足既是登高;弦,绷得太紧会断;人,思虑过度会疯;水至清无鱼,人至真无友,山至高无树;适度,不是中庸,而是一种明智的生活态度。

导读:本篇文章讲解 C++之类模板,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

作者:非妃是公主
专栏:《笔记》《C++》
个性签:顺境不惰,逆境不馁,以心制境,万事可成。——曾国藩

在这里插入图片描述

在假期闲来无事,想到之前对模板还不是很清楚,而模板分为模板类和模板函数,而模板函数很自然地包含在模板类之中,所以就写了个模板数组类。

本着自己学习的一贯做法,优先从最简单的问题入手,领悟思想。

先来看一下代码:

下面展示一些 内联代码片

Myfarray.h
#pragma once
#include<iostream>

using namespace std;
template<typename T>
class Myfarray {
private:
	int m_num;
	T* m_data;
public:
	Myfarray(int n) :m_num(n) {
		m_data = new T[n];
		for (int i = 0; i < m_num; i++) {
			m_data[i] = 0;
		}
	}
	~Myfarray() {
		delete[]m_data;
	}

	Myfarray<T>& operator=(const Myfarray<T>& myf) {
		if (&myf == this)return*this;
		m_num = myf.m_num;
		delete[]m_data;
		m_data = new int[m_num];
		for (int i = 0; i < m_num; i++) {
			m_data[i] = myf.m_data[i];
		}
		return *this;
	}

	Myfarray(const Myfarray<T>& myf) {
		m_num = myf.m_num;
		m_data = new int[m_num];
		for (int i = 0; i < m_num; i++) {
			m_data[i] = myf.m_data[i];
		}
	}

	T& operator[](int i) {
		return m_data[i];
	}
	friend ostream& operator<<<T>(ostream& os, Myfarray<T>& myf);
	friend istream& operator>><T>(istream& is, Myfarray<T>& myf);
};
template<typename T>
ostream& operator<<(ostream& os, Myfarray<T>& myf) {
	for (int i = 0; i < myf.m_num; i++) {
		os << myf.m_data[i];
	}
	return os;
}
template<typename T>
istream& operator>>(istream& is, Myfarray<T>& myf) {
	for (int i = 0; i < myf.m_num; i++) {
		cout << "请输入第" << i << "个数:" << endl;
		is >> myf.m_data[i];
		//cout << endl;
	}
	return is;
}

下面展示一些 内联代码片

main.cpp
#include"myfarray.h"
int main() {
	Myfarray<int> myf1(5);

	cin >> myf1;
	cout << myf1 << endl;
	Myfarray<int> myf2(7);
	cin >> myf2;
	cout << myf2 << endl;
	Myfarray<int> myf3(myf2);
	cout << myf3 << endl;
	cout << myf3[2] << endl;
	system("pause");
}

图为运行结果:
在这里插入图片描述

代码虽简单,可其中却包含了几乎与模板相关的所有知识点。其中包含:

  1. 类模板的定义
  2. 类模板成员函数的定义(函数模板的定义)
  3. 实例化类模板
  4. 默认模板参数

在C++业内有句行话,所有C++代码都要自己真正敲一遍才算学会。的确如此,对于一门强类型语言来讲,弹性空间几乎为0,你永远无法预料到会遇到什么样的错误。

只要有面向对象基础,看懂代码并不难,所以在此不再赘述。

不过在此提出一种C++学习方法,就是注重实践,遇到新的语法,标准,先看一下,然后在自己尝试写一个实例出来(比如学习模板,那么写个类模板出来),效果会很不错。

下面提出在编写程序中遇到的一些问题:
报错一:

1>main.obj : error LNK2019: 无法解析的外部符号 "class std::basic_ostream<char,struct
 std::char_traits<char> > & __cdecl operator<<(class std::basic_ostream<char,struct 
 std::char_traits<char> > &,class Myfarray<int> &)" (??6@YAAAV?$basic_ostream@DU?
 $char_traits@D@std@@@std@@AAV01@AAV?$Myfarray@H@@@Z),函数 _main 
 中引用了该符号

问题分析:根据错误信息,定位到输出运算符(<<)的重载。
修改办法:
首先,找到该函数的声明=》
在这里插入图片描述
在找到该函数的定义=》
在这里插入图片描述
然后,经过思考,仅在声明中加了一个<>符号,如图:在这里插入图片描述

问题解决。

错误原因:由于重载的<<运算符函数,是在类模板的友元函数,而Myfarray是一个抽象类,其中的函数就需要实例化。我们需要告诉编译器,重载的<<函数(输出运算符函数),是属于类模板的,这样才能避免找不到定义。

于是,你会发现解决方案还有以下方法,如:
①在声明处加,如图:
在这里插入图片描述
总之,对于<<运算符重载函数而言,只需要将其实例化就可以。

②直接将友元函数声明为内联函数形式,如:
在这里插入图片描述
经过测试,代码均运行成功!!

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/130593.html

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!