1.第一个最简单的类模板案例

#include "mainwindow.h"

#include <QApplication>

#include <QPushButton>

#include <QLabel>

template<class T>

class run

{

public:

T w;

void show()

{

w.show();

}

void settext()

{

w.setText("A");

}

};

int main(int argc, char *argv[])

{

QApplication a(argc, argv);

run<QPushButton> run1;

run1.show();

run1.settext();

return a.exec();

}

2.类模板案例2

#include <iostream>
#include <typeinfo>
 
using namespace std;
 
int add(int a,int b)
{
    std::cout << "add int\n";
    return a + b;
}
 
double add(double a,double b)
{
    std::cout << "add double\n";
    return a + b;
}
 
template<class T>
T add(T a,T b)
{
    std::cout << "add T\n";
    return a + b;
}
 
class com1
{
public:
    int a;
    int b;
    int add()
    {
        return a + b;
    }
};
 
class com2
{
public:
    double a;
    double b;
    double add()
    {
        return a + b;
    }
};
 
template <class T>
class com
{
public:
    T a;
    T b;
    T add()
    {
        std::cout << typeid(T).name() << std::endl;
        return a + b;
    }
};
 
int main()
{
    com<double> comx;
    comx.a = 19;
    comx.b = 29.8;
    std::cout << comx.add() << std::endl; //结果四48.8
 
    com2 com21;
    com21.a = 10;
    com21.b = 20.9;
    std::cout << com21.add() << std::endl;  //结果是30.9
 
    return 0;
}
  1. 多种类型的类模板
案例:

#include<iostream>

#include<string>

//定义两种数据类型的类模板

//STL数据结构,算法,适合任何类型

//定义两种数据类型的类模板

template<class T1,class T2>

class myclass

{

public:

T1 t11;

T2 t22;

myclass(T1 t111, T2 t222) :t11(t111), t22(t222)

{

}

void print()

{

std::cout << t11 << "  " << t22 << std::endl;

}

};

void main()

{

myclass<int, double> my1(10, 20.8);

my1.print();

myclass<double, std::string> my2(20.8, "123456abc");

my2.print();

std::cin.get();

}

3.自定义类模板,类模板的默认类型

myArray.h

#pragma once //只包含一次,只是针对VS下的

//类模板可以有一个默认的值

template<class T = int>

class myArray

{

public:

myArray();

~myArray();

};

myArray.cpp

#include "myArray.h"

template <class  T = int>//每一个函数都需要加上一个默认的值

myArray<T>::myArray()   //类模板成员函数在外部,需要加载类型初始化

{

std::cout << "构造" << typeid(T).name() << std::endl;

}

template <class  T = int>

myArray<T>::~myArray()

{

std::cout << "销毁" << typeid(T).name() << std::endl;

}

main.cpp

#include <iostream>

#include <array>

#include <string>

#include "myArray.h"

#include "myArray.cpp"  //类模板的成员函数没有实例化,不会自动找到,需要手动包含

using namespace std;

void main1()

{

myArray<double> my1;

myArray<> my2;//C++11的新功能(如果有默认类型了,这时候类型可以为空)

std::cin.get();

//结果输出

//构造double

//构造int

}

void main()

{

array<string, 5>strarray = { "calc", "mspaint", "notepad", "tasklist", "pause" };

for (int i = 0; i < strarray.size();i++)

{

std::cout << strarray[i].c_str() << std::endl;

}

std::cin.get();

//运行结果是:

//calc

//mspaint

//notepad

//tasklist

//pause

}

4.数组的模板实现(类似c++中array的功能)

Array.h

#pragma once

template<class T,int n>

class Array

{

public:

Array();

Array(int length);

~Array();

int size();

T get(int num);

T & operator [](int num);//重载[]

void set(T data, int num);

public:

T *pt;

};

Array.cpp

#include "Array.h"

template<class T, int n>//int n不可以修改,不是类的内部成员

Array<T,n>::Array()

{

this->pt = new T[n];

}

/*****************************

*初始化length个长度的数组

*****************************/

template<class T, int n> //每一个函数都必须模板

Array<T, n>::Array(int length)

{

this->pt = new T[length];

}

/*****************************

*析构数组

*****************************/

template<class T, int n>//每一个函数都必须模板

Array<T, n>::~Array()

{

//n = 0;

delete[] this->pt;

}

/*****************************

*获得Array的大小

*****************************/

template<class T,int n>

int Array<T, n>::size()

{

return n;

}

/*****************************

*获得第n个元素

*****************************/

template<class T, int n>//每一个函数都必须模板

T Array<T, n>::get(int num)//num是数组的下标

{

if (num >= n || num < 0)//报错

{

//异常

}

else

{

return *(this->pt + num);

}

}

/*****************************

*设置第i个元素的值

*****************************/

template<class T,int n> //每一个函数都必须模板

void Array<T, n>::set(T data,int num)

{

if (num < 0 || num >= n)

{

}

else

{

*(pt + num) = data;

}

}

/*****************************

*重载[]

*****************************/

template<class T, int n>//每一个函数都必须模板

T& Array<T, n>::operator [](int num)

{

if (num < 0 || num >= n)

{

}

else

{

return *(pt + num);

}

}

测试Array的主函数:

#include <iostream>

#include <string>

#include "Array.h"

#include "Array.cpp"

using namespace std;

void main1()

{

Array<int, 5> myarray;

for (int i = 0; i < myarray.size(); i++)

{

//设置第i个元素的值为i

myarray.set(i,i);

std::cout << myarray[i] << std::endl;

}

std::cin.get();

//打印结果是:

//0

//1

//2

//3

//4

}

/************************************

*通过函数模板实现打印Array中的元素

************************************/

template<class T,int n> //类模板作为参数,类型无比明确

void print(Array<T, n> &myArray)

{

for (int i = 0; i < myArray.size();i++)

{

std::cout << myArray[i] << std::endl;

}

}

void main()

{

Array<int, 5> myarray;

//调用size()函数,求Array中的大小

for (int i = 0; i < myarray.size();i++)

{

myarray.set(i,i);

}

//通过函数模板实现打印array中的数据

print(myarray);

std::cin.get();

//打印结果是:

//0

//1

//2

//3

//4

}

5.友元类类模板

#include<iostream>

//友元类必须声明类的存在,

//需要声明友元类,必须要与类型相关

template<class T> class myclass;

template<class T> class runclass;

template<class T>

class myclass

{

public:

myclass(T t) :x(t){}

friend class runclass<T>;//声明友元类

private:

T x;//模板友元类

};

template<class T>

class runclass

{

public:

void print(const myclass<T> & my)

{

//直接访问传递进来的类的私有变量

std::cout << my.x << std::endl;

}

};

void main()

{

myclass<double> my1(19.8);

//myclass中定义的友元类

runclass<double> run1;

run1.print(my1);

std::cin.get();

}

6.友元函数

#include<iostream>

template <class T> class myclass;   //这里一定要声明这个友元类

template <class T> void printA(myclass<T> my);

template <class T>

class myclass

{

public:

myclass(T t) :x(t)

{

}

friend void print(myclass<T> my)

{

std::cout << my.x << std::endl;

}

//友元函数如果在外部,第一声明要加类型T

//必须要声明类还有函数

friend void printA<T>(myclass<T> my);

private:

T x;  //模板友元类

//int y;访问与T无关的类型,普通友元类

};

template <class T>

void printA(myclass<T> my)

{

std::cout << my.x << std::endl;

}

void main()

{

myclass<int> my1(10);

myclass<double> my2(10.9);

printA(my1);

print(my2);

std::cin.get();

//运行结果:

//10

//10.9

}

7.类模板与静态变量,同种类型的实例共享同一个静态变量,不同类的不共享同一个变量

案例:

#include <iostream>

#include<string>

//类模板的static成员,对象,类名《类型》

//不同类型的静态成员变量,地址不一样

//相同类型的静态成员变量,地址一样

template<class T>

class myclass

{

static int data;

public:

static int num;//声明

T a;

myclass(T t) :a(t)

{

num++;

data++;

}

static void run()

{

//this->a;

std::cout << data << std::endl;

std::cout << typeid(T).name() << "\n";

}

};

template<class T>

int  myclass<T>::num = 0;

template<class T>

int  myclass<T>::data = 0;

//静态变量,静态函数,同种类型的时候共享的静态变量

//类型不同,不共享静态变量

void main1()

{

myclass<int> my1(10);

myclass<double> my2(10.9);

myclass<int> my4(10);

myclass<int>::run();

myclass<int>::run();

myclass<int>::run();

my1.run();

myclass<double>::run();

std::cin.get();

//运行结果:

//2

//int

//2

//int

//2

//int

//1

//double

}

void main()

{

myclass<int > my1(10);

myclass<double > my2(10.9);

myclass<std::string > my3("1234");

myclass<int > my4(10);

std::cout << &my1.num << std::endl;

std::cout << &my2.num << std::endl;

std::cout << &my3.num << std::endl;

std::cout << &my4.num << std::endl;

std::cout << &myclass<int >::num << std::endl;

std::cout << &myclass<float >::num << std::endl;

std::cin.get();

}

8.类模板之间的继承

#include<iostream>

#include <string>

//模板类之间的继承

//类模板可以直接继承类模板,类型必须传递

//普通类继承类模板,需要明确类型实例化类模板

//类模板继承普通类,常规的操作方式

//类模板当作普通哦类,需要模板参数对类进行实例化

template<class T>  //抽象模板类

class myclass

{

public:

T x;

myclass(T t) :x(t)

{

}

virtual void print() = 0;

};

template<class T>

class newclass :public myclass<T> //继承必须明确类型

{

public:

T y;

newclass(T t1, T t2) :myclass(t1), y(t2) //调用父类的构造函数

{

}

void print()

{

std::cout << x << "   " << y << std::endl;

}

};

void main()

{

myclass<int> *p = new newclass<int>(10,9);

p->print();

std::cin.get();

//运行结果是:10    9

}

当写成下面的函数时

void main()

{

newclass<std::string> my1("abc", "xyz");

my1.print();

std::cin.get();

//运行结果是:abc   xyz

}

9.类模板继承普通类,普通类继承类模板等情况

#include<iostream>

#include <string>

//模板类之间的继承

//类模板可以直接继承类模板,类型必须传递

//普通类继承类模板,需要明确类型实例化类模板

//类模板继承普通类,常规的操作方式

//类模板当作普通哦类,需要模板参数对类进行实例化

template<class T>  //抽象模板类

class myclass

{

public:

T x;

myclass(T t) :x(t)

{

}

virtual void print() = 0;  //可以带有纯虚函数

};

template<class T>

class newclass :public myclass<T> //继承必须明确类型

{

public:

T y;

newclass(T t1, T t2) :myclass(t1), y(t2) //调用父类的构造函数

{

}

void print()

{

std::cout << x << "   " << y << std::endl;

}

};

//普通类

class xyz

{

public:

int x;

int y;

int z;

xyz(int a, int b, int c) :x(a), y(b), z(c)

{

}

void print()

{

std::cout << x << y << z;

}

};

template<class T>

class newxyz :public xyz

{

public:

T a;

//构造的时候给父类初始化

newxyz(T t1, int a1, int b1, int c1) :xyz(a1, b1, c1), a(t1)

{

}

void print()

{

std::cout << "Ta=" << a << std::endl;

std::cout << x << y << z << std::endl;

}

};

/*普通类继承模板类的时候这是要确定类型*/

class classrun :public newxyz<int>

{

public:

int d = 1000;

//下面的构造函数要确定类型

classrun(int a2, int b2, int c2, int d2) :newxyz<int>(a2, b2, c2, d2)

{

}

void print()

{

std::cout << d << x << y << z << a;

}

};

void main1()

{

classrun run1(1, 2, 3, 4);

run1.print();

std::cin.get();

//运行结果是:10002341

}

void main()

{

std::string  str1 = "china";

newxyz<std::string> new1(str1, 10, 90, 89);

new1.print();

std::cin.get();

//运行结果是:

//Ta=china

//109089

}

10.类模板与友元函数,类模板与友元类

#include <iostream>

#include <string>

#include <vector>

template<class T> class myclass;

template<class T> void print(myclass<T> & my, T t1);

template<class T>

class myclass

{

public:

//friend void print(myclass<T> & my,T t1);

//友元函数放在模板类的内部,实现重载

friend void print(myclass<T> & my, T t1);

friend myclass * operator+(const myclass<T> & my1, const myclass<T> & my2)

{

//下面的情况在栈上,用完了马山释放

//myclass class1

//堆上申请一个

myclass * p = new myclass(my1.x + my2.x, my1.y + my2.y);

return p;

}

myclass(T t1, T t2) :x(t1), y(t2)

{

}

//访问私有需要友元

private:

T x;

T y;

};

template<class T>

void print(myclass<T> & my, T t1)

{

std::cout << typeid(t1).name() << std::endl;

std::cout << my.x << "   " << my.y << std::endl;

}

using namespace std;

void main()

{

myclass<int> my1(19, 29);

vector<int> v1;

vector<vector<int>> v2;

vector<vector<vector<int>>> v3;

//通过下面的方式对类型进行简写

using VEC = vector<vector<vector<int>>>;  //C++11简写

VEC v4;//等价于三维int类型数据,模板

std::cin.get();

}

案例2

#include<iostream>

using namespace std;

//这里要声明模板类和友元函数

template<class T> class Object;

template<class T> void fun(const Object<T> &);

template<class T>

class Object

{

private:

T _d;

public:

Object(T d) :_d(d){}

//声明友元函数

friend void fun<T>(const Object<T> &);

};

template<class T>

void fun(const Object<T> & obj)

{

cout << obj._d << endl;

}

int main()

{

Object<double> obj(111.4);

fun<double>(obj);

std::cin.get();

return 0;

//运行结果:111.4

}

类模板与友元类

#include <iostream>

using namespace std;

//定义友元类和友元函数

template<class T> class myclass;

template<class T> void print(const myclass<T> &);

template<class T> class runclass;

template<class T>

class myclass

{

private:

T x;

T y;

public:

myclass(T t1, T t2) :x(t1), y(t2)

{

}

//友元必须类名

friend void print<T>(const myclass<T> &);

friend class runclass<T>;

};

template<class T>

void print(const myclass<T> &my)

{

std::cout << my.x << "   " << my.y << std::endl;

}

template<class T>

class runclass

{

public:

void print(const myclass<T> & my)

{

std::cout << my.x << "  " << my.y << std::endl;

}

};

void main()

{

myclass<int> my1(19, 29);

myclass<int> my2(11,1);

print(my2);

runclass<int> runclass1;

runclass1.print(my1);

std::cin.get();

//运行结果:

//11    1

//19    29

}

11.类模板当作模板参数

#include<iostream>

#include <string>

using namespace std;

//类模板当作一个类的参数

//设计STL的时候用到

template<class T>

class ren  //一个通用的类的类模板

{

public:

T name;

ren(T t) :name(t)

{

}

};

//使用类模板当作模板参数的类

template<template<class T> class T1>

class people

{

public:

T1<string> t1x = "123123";//T1必须实例化 。必须结合

T1<string>  num = "ABC";  //等价于ren类型

//T1 x

people(T1<string> &t1)

{

std::cout << typeid(t1).name() << std::endl;

std::cout << typeid(T1).name() << std::endl;

std::cout << t1.name << std::endl;

t1x = t1;

num = t1;

}

};

void main()

{

ren<string> ren1("hello8848");//基本数据类型

people<ren> people1(ren1);  //嵌套的类模板

std::cout << people1.t1x.name << std::endl;

std::cout << people1.num.name << std::endl;

std::cout << ren1.name << std::endl;

std::cin.get();

}

运行结果:

12.类包装器

#include <iostream>

//类包装器,实现一个操作接口,操作多个类的方法

template<typename T,typename F>

T run(T t, F f)

{

return f(t);

}

int add(int num)

{

return num + 10;

}

class myclass

{

public:

int  num;

myclass(int data) :num(data)

{

}

int operator ()(int X)

{

return X*num;

}

};

class myclassA

{

public:

int  num;

myclassA(int data) :num(data)

{

}

int operator ()(int X)

{

std::cout << "A\n";

return X - num;

}

};

void main1()

{

myclass my1(5);

//函数作为参数

std::cout << run(101, my1) << std::endl;

//函数作为参数,下面的重载调用了()操作符

std::cout << run(101, myclassA(51)) << std::endl;

std::cin.get();

//运行结果是:

//505

//A

//50

}

void main()

{

auto num = 100;

auto func = add;

//调用add函数

std::cout << run(num, add) << std::endl;

std::cin.get();

//运行结果:110

}

13.类嵌套

#include<iostream>

//类的嵌套

class myclass

{

public:

class newclass

{

public:

int num;

} new1;

};

class newnewclass :public myclass

{

};

void main1()

{

newnewclass newx;

newx.myclass::new1.num = 10;

std::cout << newx.new1.num;

std::cin.get();

//运行结果:10

}

void main()

{

myclass myclass1;

myclass1.new1.num = 19;

std::cout << myclass1.new1.num;

std::cin.get();

//运行结果:19

}

14.类模板嵌套

#include <iostream>

template<class T>

class myclass

{

public:

class newclass

{

public:

int num;

} new1;  //定义的方式

newclass new2;

template<class V>

class runclass

{

public:

V v1;

};//类模板后面不可以直接初始哈

runclass<T> t1;

runclass<double> t2;

};

void main()

{

myclass<int> my1;

my1.new1.num = 10;

//给嵌套类中的变量赋值

my1.t1.v1 = 12;

//给嵌套类中的变量赋值

my1.t2.v1 = 12.9;

std::cout << my1.t1.v1 << "\n" << my1.t2.v1;

std::cin.get();

//运行结果:

//12

//12.9

}

类模板,多种类型的类模板,自定义类模板,类模板的默认类型,数组的模板实现,友元和类模板,友元函数,类模板与静态变量,类模板与普通类之间互相继承,类模板作为模板参数,类嵌套,类模板嵌套,类包装器相关推荐

  1. 类型转换,类与类之间的转换,继承关系,继承与静态变量,子类父类重名,多继承,虚基类

     常量的基本类型转换,例如:int num(10.8),这种方式是隐式转换. 通过函数的构造函数实现转换. 类类转换函数,当构造函数不能将类型转换成基本类型时.所以就有了类类转换函数,通过这种方式 ...

  2. Java 枚举类型原理分析为什么枚举比用静态变量多消耗两倍的内存

    一 起源:枚举是一种特殊的数据类型,一般用来列举有限个.同类型的常量.它能保证参数的安全性,如方法声明传入的参数,必须是指定枚举中的常量.但是Android开发文档指出,使用枚举会比使用静态变量多消耗 ...

  3. java 静态变量和非静态_Java中静态和非静态变量之间的区别

    变量为我们提供了程序可以操纵的命名存储.Java中的每个变量都有一个特定的类型,该类型确定变量的内存大小和布局.可以存储在该内存中的值的范围:以及可以应用于该变量的一组操作. 静态变量 静态变量也称为 ...

  4. php定义常量和静态常量的区别,php静态变量与自定义常量的区别实例详解

    php 静态变量与自定义常量的使用方法 ⚑ 静态变量的声明与使用 ⚑ 自定义常量的使用方式 什么是静态变量? 静态变量是指用static声明的变量,这种变量与局部变量的区别是,当静态变量离开了它的作用 ...

  5. 笔记②:牛客校招冲刺集训营---C++工程师(面向对象(友元、运算符重载、继承、多态) -- 内存管理 -- 名称空间、模板(类模板/函数模板) -- STL)

    0618 C++工程师 第5章 高频考点与真题精讲 5.1 指针 & 5.2 函数 5.3 面向对象(和5.4.5.5共三次直播课) 5.3.1 - 5.3.11 5.3.12-14 友元 友 ...

  6. c++模板类静态成员变量_一文讲透父子类中静态变量,成员变量初始化顺序原理...

    推荐: 从面试到入职到离职,我在B站工作的30天时光 爱了爱了,Alibaba顶级MySQL调优手册到手,加薪妥了 爱了爱了,Spring Cloud Alibaba内部微服务架构笔记真的太牛了 本文 ...

  7. Long类型传到前端失去精度(2):Long类型不是实体类的某一个字段,Long类型是一个函数的返回值

    Long类型传到前端失去精度(2):Long类型不是实体类的某一个字段,Long类型是一个函数的返回值 又是转换Mybatis-Plus的一天,又遇到了之前熟悉的问题:Long类型传到前端失去精度.可 ...

  8. Hibernate中的Entity类之间的继承关系之一MappedSuperclass

    在hibernate中,Entity类可以继承Entity类或非Entity类.但是,关系数据库表之间不存在继承的关系.那么在Entity类之间的继承关系,在数据库表中如何表示呢? Hibernate ...

  9. 某IT公司有多名员工,按员工负责的工作不同,进行了部门的划分(研发部员工、维护部员工)。完成员工体系中所有类的定义,并指定类之间的继承关系。进行xx工程师类的对象创建,完成工作方法的调用。

    某IT公司有多名员工,按员工负责的工作不同,进行了部门的划分(研发部员工.维护部员工).研发部根据所需研发的内容不同,又分为JavaEE工程师.Android工程师:维护部根据所需维护的内容不同,又分 ...

最新文章

  1. QIIME 2用户文档. 8数据导入Importing data(2018.11)
  2. Elasticsearch 常用配置参数总结
  3. 解决 Python shell 中 Delete/Backspace 键乱码问题
  4. 光栅衍射主极大个数_大学物理——光的干涉和衍射(二)
  5. 聊聊flink Table的OrderBy及Limit
  6. 突发!哈佛要求本科生5天内搬走,国际学生恐无家可归
  7. 区块链网络安全平台Hapi Protocol将在Poolz上进行 IDO
  8. 用于android天气开发的背景图,Android开发天气预报APP的设计与实现毕业设计.pdf
  9. TensorFlow相关教程:使用tf.data加载图片
  10. 矩阵的秩(Rank)
  11. 希尔伯特变换到底有什么用
  12. 需求分析师面试题案例_如何准备作为分析师的业务案例面试
  13. 高压带电显示器局放检测面板式四合一局放在线监测/带电故障显示/无线测温装置
  14. latext配置 vscode_VSCode配置LaTeX编辑器
  15. 离职 需要注意三个问题
  16. RDF和SPARQL
  17. 为什么图像成像时近大远小?
  18. en-win7-x64-sp1 + vs2015.3 + Lenovo Z470 装机镜像
  19. 自学软件测试,该读些什么书籍?
  20. 建筑CAD软件导出超大T3或T8格式图纸时卡顿怎么办?

热门文章

  1. Spring IoC(二)IoC容器的初始化过程
  2. VTK:定向包围圆柱体用法实战
  3. wxWidgets 的打印演示
  4. wxWidgets:wxTaskBarIcon类用法
  5. boost::uuid::nil_generator相关的测试程序
  6. boost::rotate相关的测试程序
  7. BOOST_PROTO_EXTENDS_MEMBERS宏相关的测试程序
  8. boost::mp11::mp_less相关用法的测试程序
  9. boost::detail::conversion::try_lexical_convert用法的测试程序
  10. ITK:计算图像谱密度