1.什么是继承呢
继承就是一个类继承另一个类
然后这个类就他他继承类的成员(类型)和行为(函数)
继承的实质: 父类(基类)当中的属性,子类(派生类)中也有一份,这一份的属性是由继承方式的决定的。
继承的方法
class 子类名: 继承方式 父类名
{
};
//继承方式: 权限限定词
//public 公有
//protected: 保护
//private: 私有继承
class 派生类名:继承方式 基类名
{
//生成新的属性和行为
};
1.1继承权限问题
public | protected | private | |
---|---|---|---|
public :继承 | public | protected | 不可访问 |
protected:继承 | protected | protected | 不可访问 |
private:继承 | private | private | 不可访问 |
1.2 继承具有遗传性
继承的属性是一值存在的,无论被继承多少代,都是存在,所以一般类的击沉不会写太多层数,导致类很冗长。
1.3继承中的构造函数使用方法
#include<iostream>
using namespace std;
class A
{
public:
A(string name) :name(name)
{
cout << "A的构造函数" << endl;
}
protected:
string name;
};
class B :public A//B public继承A
{
public:
B(string name, int year) :year(year) ,A(name)
{
cout << "B的构造函数";
}//要用b的构造函数同时也要构造A A构造用A的构造函数就可以
protected:
int year;
};
多个继承
//自己的属性怎样初始化都可以,但是父类的中继承下来的属性,必须调用父类的构造函数初始化
#include<iostream>
using namespace std;
class A
{
public:
A(string name) :name(name)
{
cout << "A的构造函数" << endl;
}
protected:
string name;
};
class B
{
public:
B( int year) :year(year)
{
cout << "B的构造函数";
}
protected:
int year;
};
class C :public A, protected B
{
public:
C(string name, int year, int num) :num(num), B(year), A(name)
{
cout << "C的构造函数";
};
protected:
int num;
};
继承中构造函数顺序和析构函数的顺序
构造函数的顺序至于继承的顺序有关
不管你构造函数怎么写
#include<iostream>
using namespace std;
class A
{
public:
A(string name) :name(name)
{
cout << "A的构造函数" << endl;
}
~A()
{
cout << "A的析构函数" << endl;
}
protected:
string name;
};
class B
{
public:
B( int year) :year(year)
{
cout << "B的构造函数" << endl;;
}
~B()
{
cout << "B的析构函数" << endl;
}
protected:
int year;
};
class C :public A, protected B
{
public:
C(string name, int year, int num) :num(num), B(year), A(name)
{
cout << "C的构造函数" << endl;;
};
~C()
{
cout << "C的析构函数" << endl;
}
protected:
int num;
};
int main()
{
C c("cc", 18, 20);
//理解就是这样想A B 都是C的爹 所有先构造A B 然后因为A
在前面所有先构造A 构造B 最后构造C
析构顺序和构造顺序想反 先C B A
return 0;
}
2.模板类
模板: 把数据类型当做一个参数(未知参数)
template <class T,....>//主要用这个
template <typename T>
2.1模板函数
template<class _Ty>
_Ty Max(_Ty one, _Ty two)
{
return one > two ? one : two;
}
int main()
{
cout << Max(1, 2) << endl;
cout << Max(1.1, 1.2)<<endl;
cout << Max('a', 'b');
return 0;
}
这是一个求最大值的函数如果有了模板就不用每次去重新构造不同类型了
多个未知类型
template <class _Ty1,class _Ty2,class _Ty3>
void print(_Ty1 one, _Ty2 two, _Ty3 three)
{
cout << one << endl;
cout << two << endl;
cout << three << endl;
}
操作自定义类型的函数模板
class MM
{
public:
MM() {};
MM(string name, int age) :name(name), age(age) {};
string& getname()
{
return this->name;
}
int& getage()
{
return this->age;
}
bool operator >(MM& one )
{
return one.getage() > this->age;
}
protected:
string name;
int age;
};
int main()
{
//操作自定义类型
//因为在类中重载了>
cout << Max(MM("kk", 18), MM("JJ", 15)).getage() << endl;
cout << Max(MM("kk", 18), MM("JJ", 15)).getname() << endl;
return 0;
}
2.2类模板
//1.模板类不是一个真正类,所以在用到类名的地方,都需要: 类名<未知类型> 方式的使用
//2.模板类必须显示调用,不能隐式调用
template <class _Ty>
class Data
{
public:
Data() {}
Data(_Ty data) :data(data) {}
void print();
protected:
_Ty data;
static int count;
};
//静态数据成员一样需要用template 修饰
template <class _Ty>
int Data<_Ty>::count = 0;
一个templata<class _Ty....>一个这个控制一条语句
//这个不叫做类模板
class A
{
public:
//只是单纯的成员是模板
template <class _Ty>
void print()
{
cout << "A" << endl;
}
template <class _Ty>
void print(_Ty data)
{
cout << "A:" << data << endl;
}
protected:
};
用了模板后每次有类名都要类名<T类型(自己定义的)>