首页 > 编程语言 >8.6 C++ 泛型化编程态

8.6 C++ 泛型化编程态

时间:2023-10-21 15:24:54浏览次数:32  
标签:name 8.6 int age C++ Student 泛型化 模板 template

C/C++语言是一种通用的编程语言,具有高效、灵活和可移植等特点。C语言主要用于系统编程,如操作系统、编译器、数据库等;C语言是C语言的扩展,增加了面向对象编程的特性,适用于大型软件系统、图形用户界面、嵌入式系统等。C/C++语言具有很高的效率和控制能力,但也需要开发人员自行管理内存等底层资源,对于初学者来说可能会有一定的难度。

函数模板的基本使用: 函数模板就是要实现类型参数化,实现泛型编程,就是可以动态的调整数据类型.

#include <iostream>
#include <typeinfo>

using namespace std;

// template<> 告诉编译器,下面如果出现T不要报错,T是一个通用的类型
template<class T>
void MySwap(T &x, T &y)
{
  T tmp = x;
  x = y;
  y = tmp;
}

template<class T>
T MyAdd(T &x, T &y)
{
  return x + y;
}

// 此处的typename = class
template<typename T>
void MyPrint()
{
  T number;
  cout << "type = " << typeid(T).name() << endl;
}

int main(int argc, char *argv[])
{
  // 自动类型推导: 必须要有参数才能推到(根据参数来确定类型)
  int x = 10, y = 20;
  MySwap(x, y);
  cout << "x= " << x << endl;

  int ret = MyAdd(x, y);
  cout << "x+y = " << ret << endl;

  // 手动类型指定: 如果参数不一致,可能会报错,此时我们需要告诉它类型
  MySwap<int>(x, y);
  cout << "x= " << x << endl;

  // 针对无参数函数处理: 有些函数没有参数,我们需要指定模板默认类型
  MyPrint<int>();
  MyPrint<double>();

  system("pause");
  return 0;
}

我们在上面的案例基础上进行一定的加强,通过模板实现一个选择排序,我们可以传入任意的数据类型,都可被解析.

#include <iostream>
#include <typeinfo>

using namespace std;

template<class T>
void MySwap(T &x, T &y)
{
  T tmp = x;
  x = y;
  y = tmp;
}

template<class T>
void SelectSort(T Array[], int len)
{
  for (int x = 0; x < len; x++)
  {
    int max = x;
    for (int y = x + 1; y < len; y++)
    {
      if (Array[max] > Array[y])
        max = y;
    }
    if (max != x)
      MySwap(Array[max], Array[x]);
  }
}

template<class T>
void MyPrint(T Array[], int len)
{
  for (int x = 0; x < len; x++)
    cout << Array[x] << " ";
}

int main(int argc,char *argv[])
{
  int Int_Array[10] = { 4, 7, 8, 2, 1, 8, 0, 3, 2, 7 };
  SelectSort<int>(Int_Array, 10);
  MyPrint<int>(Int_Array, 10);

  char Char_Array[] = "hello lyshark";
  int len = sizeof(Char_Array) / sizeof (char);
  SelectSort<char>(Char_Array, len);
  MyPrint<char>(Char_Array, len);

  system("pause");
  return 0;
}

实现模板具体化: 通过自定义模板函数,解决模板的局限性问题.

#include <iostream>

using namespace std;

class Student
{
public:
  char *m_name;
  int m_age;
public:
  Student(char *name, int age)
  {
    this->m_name = name;
    this->m_age = age;
  }
};

template<class Student>
bool MyCompare(Student &x, Student &y)
{
  if (x.m_age == y.m_age)
    return true;
  return false;
}


int main(int argc, char *argv[])
{
  Student stu1("lyshark", 22);
  Student stu2("admin", 33);

  bool ret = MyCompare(stu1, stu1);
  cout << ret << endl;

  bool ret1 = MyCompare(stu1, stu2);
  cout << ret1 << endl;

  system("pause");
  return 0;
}

定义并使用类模板: 类模板不支持类型的自动推导,所以必须在调用时Student<string, int>显式指定好类型.

#include <iostream>
#include <string>

using namespace std;

template<class NameType = string,class AgeType = int>  // 类模板可以指定默认参数
class Student
{
public:
  string m_name;
  int m_age;

public:
  Student(NameType name,AgeType age)
  {
    this->m_name = name;
    this->m_age = age;
  }
  void show() { cout << "name = " << m_name << endl; }
};

template<class Student>
bool MyCompare(Student &x, Student &y)
{
  if (x.m_age == y.m_age)
    return true;
  return false;
}

int main(int argc, char *argv[])
{
  // 调用类模板是要在类后面添加参数列表
  Student<string, int> stu1("lyshark", 25);
  stu1.show();

  system("pause");
  return 0;
}

类模板做函数参数传递: 此处我们将类模板Student<string, int>当做函数参数传递给MyPrint函数.

#include <iostream>
#include <string>

using namespace std;

template<class NameType,class AgeType>
class Student
{
public:
  string m_name;
  int m_age;

public:
  Student(NameType name,AgeType age)
  {
    this->m_name = name;
    this->m_age = age;
  }
  void show() { cout << "name = " << m_name << endl; }
};

void MyPrintA(Student<string, int> &ptr)
{ ptr.show(); }

template<class T1,class T2>
void MyPrintB(Student<T1,T2> &ptr)
{ ptr.show(); }

template<class T>
void MyPrintC(T &ptr)
{ ptr.show(); }

int main(int argc, char *argv[])
{
  // 1. 指定传入的类型直接调用
  Student<string, int> stu1("lyshark", 25);
  MyPrintA(stu1);

  // 2. 参数模板化调用
  Student<string, int> stu2("admin", 10);
  MyPrintB(stu2);

  // 3.整体模板化调用
  Student<string, int> stu3("root", 10);
  MyPrintC(stu3);

  system("pause");
  return 0;
}

类模板类内定义类外实现: 类模板同样支持类内定义模板类型,在类外部对其进行具体的实现.


#include <iostream>
#include <string>

using namespace std;

template<class NameType,class AgeType>
class Student
{
public:
  string m_name;
  int m_age;

public:
  Student(NameType name, AgeType age);
  void show();
};

// 类外实现成员构造函数
template <class NameType,class AgeType>
Student<NameType, AgeType>::Student(NameType name, AgeType age)
{
  this->m_name = name;
  this->m_age = age;
}

// 类外实现打印函数
template <class NameType,class AgeType>
void Student<NameType, AgeType>::show()
{
  cout << "Name = " << this->m_name << endl;
}

int main(int argc, char *argv[])
{
  Student<string, int> stu("lyshark", 20);
  stu.show();

  system("pause");
  return 0;
}

类模板友元函数类内实现: 友元函数就是可以让类外直接访问的函数,调用类内友元函数就像调用全局函数一样.

#include <iostream>
#include <string>

using namespace std;

template<class NameType,class AgeType>
class Student
{
  // 友元函数的类内实现
  friend void show(Student<NameType, AgeType> &ptr)
  {
    cout << "name = " << ptr.m_name << endl;
  }

private:
  string m_name;
  int m_age;
public:
  Student(NameType name, AgeType age)
  {
    this->m_name = name;
    this->m_age = age;
  }
};


int main(int argc, char *argv[])
{
  Student<string, int> stu("lyshark", 20);
  // 此处调用,类似于全局调用
  show(stu);

  system("pause");
  return 0;
}

类模板友元函数类外实现: 类外实现同理,就是现在类内声明类型作为占位符,然后在类外进行实现.

#include <iostream>
#include <string>

using namespace std;

// 类外实现必须提前声明模板的存在
template<class T1, class T2> class Student;
template<class T1, class T2> void show(Student<T1, T2> & p);

template<class T1,class T2>
class Student
{
  // 友元函数类内实现,利用空参数列表声明 (占位符)
  friend void show<>(Student<T1, T2> &ptr);

private:
  string m_name;
  int m_age;

public:
  Student(T1 name, T2 age)
  {
    this->m_name = name;
    this->m_age = age;
  }
};

// 对友元函数的类外实现
template<class T1,class T2>
void show(Student<T1,T2> &ptr)
{
  cout << "name = " << ptr.m_name << endl;
}

int main(int argc, char *argv[])
{
  Student<string, int> stu("lyshark", 20);
  // 此处调用,类似于全局调用
  show(stu);

  system("pause");
  return 0;
}

本文作者: 王瑞
本文链接: https://www.lyshark.com/post/414cc3d3.html
版权声明: 本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!

标签:name,8.6,int,age,C++,Student,泛型化,模板,template
From: https://www.cnblogs.com/LyShark/p/17779006.html

相关文章

  • 8.1 C++ 标准输入输出流
    C/C++语言是一种通用的编程语言,具有高效、灵活和可移植等特点。C语言主要用于系统编程,如操作系统、编译器、数据库等;C语言是C语言的扩展,增加了面向对象编程的特性,适用于大型软件系统、图形用户界面、嵌入式系统等。C/C++语言具有很高的效率和控制能力,但也需要开发人员自行管理内存......
  • 8.2 C++ 引用与取别名
    C/C++语言是一种通用的编程语言,具有高效、灵活和可移植等特点。C语言主要用于系统编程,如操作系统、编译器、数据库等;C语言是C语言的扩展,增加了面向对象编程的特性,适用于大型软件系统、图形用户界面、嵌入式系统等。C/C++语言具有很高的效率和控制能力,但也需要开发人员自行管理内存......
  • 8.3 C++ 定义并使用类
    C/C++语言是一种通用的编程语言,具有高效、灵活和可移植等特点。C语言主要用于系统编程,如操作系统、编译器、数据库等;C语言是C语言的扩展,增加了面向对象编程的特性,适用于大型软件系统、图形用户界面、嵌入式系统等。C/C++语言具有很高的效率和控制能力,但也需要开发人员自行管理内存......
  • 8.4 C++ 运算符重载
    C/C++语言是一种通用的编程语言,具有高效、灵活和可移植等特点。C语言主要用于系统编程,如操作系统、编译器、数据库等;C语言是C语言的扩展,增加了面向对象编程的特性,适用于大型软件系统、图形用户界面、嵌入式系统等。C/C++语言具有很高的效率和控制能力,但也需要开发人员自行管理内存......
  • 8.5 C++ 继承与多态
    C/C++语言是一种通用的编程语言,具有高效、灵活和可移植等特点。C语言主要用于系统编程,如操作系统、编译器、数据库等;C语言是C语言的扩展,增加了面向对象编程的特性,适用于大型软件系统、图形用户界面、嵌入式系统等。C/C++语言具有很高的效率和控制能力,但也需要开发人员自行管理内存......
  • C++函数如何具有多个返回值?
      本文介绍在C++语言中,使用一个函数,并返回两个及以上、同类型或不同类型的返回值的具体方法。  对于C++语言而言,其不能像Python等语言一样在一个函数中返回多个返回值;但是我们也会经常遇到需要返回两个甚至更多个值的需求。针对这种情况,我们可以通过pair、tuple(元组)等数据结......
  • C++语言基础纲要
    1、C++程序的结构2、输出语句cout<<5<<"hello"<<endl;3、输入语句cin>>a;4、变量 三要素:类型变量名值 命名规则 使用原则5、常量const关键字修饰6、基本数据类型 整型 int 3588 浮点型 double双精度float单精度 字符型 char'A''8' 布尔类型 boolt......
  • C++数据类型:
    C++数据类型:一:基本数据类型类型关键字布尔型bool字符型char整型int浮点型float双浮点型double无类型void宽字符型wchar_t其实wchar_t是这样来的:typedefshortintwchar_t;所以wchar_t实际上的空间是和shortint一样。一些基本......
  • C++学习笔记Day2
    关于String对象的一些事1.string对象来源于C++标准库<string>,表示一种可变长的字符序列,定义在命名空间std之中。2.string对象无初始值默认为空字符串。3.若是使用等号对string变量进行初始化,属于拷贝初始化,不使用等号,如strings6("hiya");strings7{"11123"};strings8(10,"c......
  • 栈实现算术优先级运算c++
    #include<stdlib.h>#include<stdio.h>#include<iostream>usingnamespacestd;#defineSTACK_INIT_SIZE100//栈初始开辟空间大小#defineSTACK_INCREMENT10//栈追加空间大小//优先级数组,2表示top>c,1表示top<c,0表示top=c,-1表示错误intprior[7][7]={{2,2,......