类模板
类模板多个类型默认类型简单数组模板
#pragma once template <class T=int>//类模板可以有一个默认的值 class myArray { public: myArray(); ~myArray(); }; #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; } #include <iostream> #include <array> #include <string> #include "myArray.h" #include "myArray.cpp"//类模板的成员函数没有实例化,不会自动找到,需要手动包含 using namespace std; void main2() { //myArray<int> my1; myArray<> my2;//C++11的新功能 std::cin.get(); } void main1() { 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(); }
#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; } }; using namespace std; void main1() { myclass<int, double> my1(10, 20.8); my1.print(); myclass<double, string>my2(20.8, "123456abc"); my2.print(); std::cin.get(); }
类模板当作函数参数
#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; //int n;//长度 }; #include "Array.h" template<class T, int n>//int n不可以修改,不是类的内部成员 Array<T,n>::Array() { //this->pt = nullptr;//空指针 //this->n = 0; this->pt = new T[n]; } template<class T, int n>//每一个函数都必须模板 Array<T,n>::Array(int length) { this->pt = new T[length]; //n = length; } template<class T, int n>//每一个函数都必须模板 Array<T,n>::~Array() { //n = 0; delete[] this->pt; } template<class T, int n>//每一个函数都必须模板 int Array<T,n>::size() { return n; } template<class T, int n>//每一个函数都必须模板 T Array<T,n>::get(int num)//num是数组的下标 { if (num >= n ||num <0)//报错 { //异常 } else { return *(this->pt + num); } } 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); } } #include <iostream> #include <string> #include "Array.h" #include"Array.cpp" using namespace std; void main1() { /* string str = "calc"; Array<string> myarray(5);//构造五个元素数组 for (int i = 0; i < myarray.size();i++) { str += "X"; myarray.set(str, i); std::cout << myarray.get(i) << std::endl; } */ std::cin.get(); } void main22() { Array<int,5 > myarray; for (int i = 0; i < myarray.size(); i++) { myarray.set(i, i); std::cout << myarray[i] << std::endl; } std::cin.get(); } 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; for (int i = 0; i < myarray.size(); i++) { myarray.set(i, i); } print(myarray); std::cin.get(); }
final_override
#include<iostream> //C++11 final override针对虚函数 //final拒绝重载,某些情况下,接口拒绝被重写 //加了final关键字的虚函数,无法被重写,预留接口 //override,警示符,声明我重写父类的方法,父类没有接口,会提示出错 class ye { public: //final”函数必须是虚函数 virtual void print() final //虚函数无法重写 { std::cout << "爷爷\n"; } virtual void run() { std::cout << "爷爷run\n"; } }; class ba:public ye { public: //警示作用,强调我覆盖了父类的方法,必须是虚函数 void runa () override { std::cout << "爸爸run\n"; } }; void main1() { ba ba1; ba1.run(); std::cin.get(); }
类模板与普通类的派生类模板虚函数抽象模板类
#include <iostream> #include <string> //模板类之间继承 //类模板可以直接继承类模板,类型必须传递 //普通类继承类模板,需要明确类型实例化类模板 //类模板继承普通类,常规的操作方式 //类模板当作普通哦类,需要模板参数对类进行实例化 template<class T> //抽象模板类 class myclass { public: T x; myclass(T t) :x(t) { } //virtual void print() //{ // std::cout << x << std::endl; //} 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(); } void mainyz() { myclass<int> *p = new newclass<int>(10,9); p->print(); std::cin.get(); } void main1() { //newclass<double> my1(10.9, 2.3); //my1.print(); newclass<std::string> my1("abc", "xyz"); my1.print(); std::cin.get(); } 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 mainy() { classrun run1(1, 2, 3, 4); run1.print(); std::cin.get(); } void mainx() { std::string str1 = "china"; newxyz<std::string> new1(str1,10,90,89); new1.print(); std::cin.get(); }
类模板友元
#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 main1() { 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类型数据,模板 } void main() { myclass<int> my1(19, 29); myclass<int> my2(11, 1); print(my1, 10); //printA(my1); myclass<int> *pclass = my1 + my2; print(*pclass,10); std::cin.get(); }
位运算算法以及类声明
不是用+号,实现加法
#include <iostream> //加减乘除,都是靠位运算, //将来从事手机端,嵌入式开发,位操作, class jia;//声明,只能声明指针或者引用 jia *pjia1; jia *& pjia2=pjia1; //jia & jia2; //jia jia1; class jia { public: jia(int a, int b) :x(a), y(b) { } int jiafa() { return x + y; } int getx() { return x; } int gety() { return y; } int newjiafa(int a, int b) { if (a == 0) { return b; } else if (b == 0) { return a; } else { int res = a^b;//先求结果 int wei = (a&b) << 1;//进位,左移,乘以2, //a+b=a^b+(a&b)<<1; std::cout << "res=" << res << " " << "wei=" << wei << "\n"; return newjiafa(res, wei); } } private: int x; int y; }; int newjiafa(int a,int b) { if (a == 0) { return b; } else if (b==0) { return a;//让相与慢慢趋势于0 } else { int res = a^b;//先求结果 int wei = (a&b) << 1;//进位,左移,乘以2, //a+b=a^b+(a&b)<<1;//表达式 std::cout << "res=" << res << " " << "wei=" << wei << "\n"; return newjiafa(res, wei); } } void main1() { //std::cout << newjiafa(11, 22) << std::endl; jia jia1(10, 9); std::cout << jia1.jiafa() << std::endl; std::cout << jia1.newjiafa(jia1.getx(), jia1.gety()) << std::endl; std::cin.get(); } void main2() { int num; std::cin >> num; int i = 0; while (num) { i++; num &= num - 1;//让数据趋向于0 } std::cout << i << std::endl; std::cin.get(); std::cin.get(); } int get1(int num) { int count = 0;//表示位数 unsigned int flag = 1;//0000001 flag // 1111 num //0000001 1 //flag 000001 //num 1111 //flag 0000010 //num 1111 // 0000010 //flag 0000100 //num 1111 // 00000100 //flag 0001000 //num 1111 // 000001000 //flag 00010000 //num 1111 //0 while (flag) { std::cout << num << " " << flag << std::endl; if (num & flag) //不为0就自增 { count++; } flag = flag << 1; } return count; } void main() { int num; std::cin >> num; int i = 0; i = get1(num); std::cout << i << std::endl; std::cin.get(); std::cin.get(); }
类模板与友元函数友元类
类模板与友元函数
#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; } friend void printA<T>(myclass<T> my); //友元函数如果在外部,第一声明要加类型T //必须要声明类还有函数 private: T x; //模板友元类 //int y;访问与T无关的类型,普通友元类 }; template <class T> void printA(myclass<T> my) { std::cout << my.x << std::endl; } void mainA() { myclass<int> my1(10); myclass<double> my2(10.9); printA(my1); print(my2); std::cin.get(); }
类模板与友元类
#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; //模板友元类 //int y;访问与T无关的类型,普通友元类 }; 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); runclass<double> run1; run1.print(my1); std::cin.get(); }
类模板当作类模板参数
#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 << people1.str << std::endl; std::cout << people1.t1x.name << std::endl; std::cout << people1.num.name << std::endl; std::cout << ren1.name << std::endl; std::cin.get(); }
static与类模板
#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 main() { 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(); //myclass<int>::data; std::cin.get(); } void mainA() { 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(); }
类嵌套以及类模板嵌套
类嵌套
#include <iostream> //类的嵌套 class myclass { public: class newclass { public: int num; }new1; }; class newnewclass :public myclass { }; void main2() { newnewclass newx; newx.myclass::new1.num=10; std::cout << newx.new1.num; std::cin.get(); } void main1() { myclass myclass1; myclass1.new1.num = 19; std::cout << myclass1.new1.num; std::cin.get(); }
类模板嵌套
#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(); }
Rtti 实时类型检测
#include <iostream> //rtti,实时类类型检测, //typeid, dynamic_cast必须依赖于虚函数表 //类型不匹配转换失败,返回为空。类型安全 //成员变量的覆盖 //虚函数有虚函数表确定数据类型 class A { public: int num; static int data; virtual void run() { std::cout << "Arun\n"; } }; int A::data=1; class B:public A { public: int num=0; static int data; void run() { std::cout << "Brun\n"; } void test() { std::cout << num<<"\n"; std::cout << "Btest\n"; } }; int B::data = 2; void main() { A a1; B b1; A *p1 = &a1; A *p2 = &b1; B *p3(nullptr); //p3 = static_cast<B *>(p1);//直接赋地址,不安全,与虚函数无关 p3 = reinterpret_cast<B*>(p2); std::cout << p3 << "\n"; p3->test(); std::cin.get(); } void main3() { A a1; B b1; A *p1 = &a1; A *p2 = &b1; B *p3(nullptr); //p3 = dynamic_cast<B*>(p2); //dynamic必须要有虚函数,根据虚函数表转换,不能转换 //转换失败为空 //类的空指针可以调用不调用数据的函数 //转换成功就是地址 std::cout << p3 << "\n"; p3->test(); std::cin.get(); } void main2() { //A *p1 = new A; //A *p2 = new B; A a1; B b1; A *p1 = &a1; A *p2 = &b1; std::cout << typeid(p1).name() <<" "<< typeid(p2).name() << std::endl; std::cout <<( typeid(p1) == typeid(p2))<<"\n"; std::cout << typeid(*p1).name() << " " << typeid(*p2).name() << std::endl; std::cout << (typeid(*p1) == typeid(*p2)) << "\n";//重载的方式判定类型是否一致 std::cin.get(); } void main1() { B b1; b1.num = 10;//覆盖现象 b1.A::num = 20; std::cout << b1.num << "\n" << b1.A::num << std::endl; std::cout << b1.data <<" "<< b1.A::data << "\n"; std::cout << &b1.data << " " << &b1.A::data << "\n"; std::cin.get(); }
高级new创建
#include <iostream> class myclass { public: myclass() { std::cout << "创建\n"; } ~myclass() { std::cout << "销毁\n"; } }; void main() { char *pcathe = new char[1024]; char *pcatheend = pcathe + 1024; std::cout <<(void*) pcathe << " " << (void*)pcatheend << std::endl; myclass *p = new(pcathe)myclass[10];//限定区域分配内存,覆盖模式 std::cout << p << std::endl; //delete[] p;一般不需要delete.自动覆盖 std::cout << p << std::endl; p = new(pcathe)myclass[10]; std::cout << p << std::endl; //delete[] p;//只能释放一次 std::cout << p << std::endl; /* myclass *pclass = new myclass[10]; std::cout << pclass << std::endl; delete []pclass; pclass = NULL; std::cout << pclass << std::endl; pclass = new myclass[10]; std::cout << pclass << std::endl; delete [] pclass; std::cout << pclass << std::endl; */ std::cin.get(); }
类以及函数包装器
#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 main() { myclass my1(5); std::cout << run(101,my1) << std::endl; std::cout << run(101, myclassA(51)) << std::endl; std::cin.get(); } void main1() { auto num = 100; auto func = add; std::cout << run(num, add) << std::endl; std::cin.get(); }
类成员函数指针
C函数指针
#include<stdio.h> int addC(int a, int b) { return a + b; } void run() { printf("\nrun"); } void main1() { int(*p)(int, int) = addC; void(*p1)() = run; printf("%d\n", p(1, 2)); printf("%d\n", (*p)(1, 2)); //*p编译器自动将*p解释为p printf("%d\n", (**********p)(1, 2)); //*p编译器自动将*p解释为p printf("%d\n", (&(**p))(1, 2)); //&没有*不可以执行,超过两个地址就不可以 //&p不能, //printf("%d\n", (&(p))(1, 2)); printf("%p,%p,%p", &p, *p, p); printf("\n%p,%p,%p", &p1, *p1, p1); //printf("%d\n", (&p)(1, 2)); //取地址,取就是CPU即将调用函数执行,C语言内嵌ASM //老版本,*p,p,&p getchar(); }
Cpp函数指针
#include <stdio.h> #include<iostream> void add(int a, int b) { std::cout << a + b << std::endl; } void mainA() { void(*p)(int, int) = add; p(1, 2); (*p)(1, 2);//函数指针,会被当作指针来处理,*p与p效果一样 (**************p)(1, 2);//函数指针,会被当作指针来处理,*p与p效果一样 (*&p)(1, 2); (*******&p)(1, 2); std::cout << (void *)p << " " << (void *)(*p) << std::endl; std::cout << typeid(p).name() << std::endl; std::cout << typeid(*p).name() << std::endl; std::cout << typeid(&p).name() << std::endl; std::cout << typeid(*&p).name() << std::endl; //C++编译器会自动将*p处理为p // std::cin.get(); }
类成员函数指针数组
#include<iostream> #include<stdio.h> //类成员函数指针,类成员函数指针数组,类成员二级函数指针 class com { private: int a; int b; public: com(int x, int y) :a(x), b(y) { } int jia(int a, int b) { return a + b; } int jian(int a, int b) { return a - b; } int cheng(int a, int b) { return a * b; } int chu(int a, int b) { return a / b; } }; void main1x() { com com1(100, 20); auto fun1 = &com::jia; int(com::*p)(int, int) = &com::jia; std::cout << (com1.*p)(10, 20) << std::endl;//引用对象,类成员函数指针 std::cout << typeid(p).name() << std::endl; std::cout << typeid(fun1).name() << std::endl; std::cin.get(); } typedef int(com::*P)(int, int); void main() { com com1(100, 20); //P fun1[4] = { &com::jia, &com::jian, &com::cheng, &com::chu }; //类成员函数指针数组 int(com::*fun1[4])(int, int) = { &com::jia, &com::jian, &com::cheng, &com::chu }; for (int i = 0; i < 4; i++) { std::cout << (com1.*fun1[i])(10, 20) << std::endl; } int(com::**funp)(int, int) = fun1;//指向类成员函数指针的指针 for (; funp < fun1 + 4; funp++) { std::cout << (com1.**funp)(10, 20) << std::endl; printf("%p", *funp); } for (int i = 0; i < 4; i++) { auto func = fun1[i]; std::cout << typeid(func).name() << std::endl; printf("%p", func); } std::cin.get(); }