类的6个成员函数
函数重载
友元函数、友元类
函数模板,类模板
#include <iostream>
//类的六个默认成员函数
using namespace std;
//构造函数
//析构函数
//拷贝构造函数
//运算符的重载
//五个不能重载的运算符
//.* :: sizeof ?: .
class Test {
public:
//构造函数——初始化类的变量
//与类同名
Test(int year, int month, int hour) {
_year = year;
_month = month;
_hour = hour;
}
//析构函数
//~+类名
~Test() {
if (_p) {
free(_p);
_p = NULL;
_year = _month = _hour = 0;
}
}
//拷贝构造函数
//构造函数的一个重载形式
//参数只有一个,必须是类类型对象的引用,不能传值
//与类同名
Test(const Test& p) {
_year = p._year;
_month = p._month;
_hour = p._hour;
_p = new int(0);//若使用默认拷贝函数(浅拷贝),则_p与p._p指向同一块内存,会出问题
}
//重载为成员函数,因为在外面无法访问类的私有变量
//重载==运算符:
bool operator==(const Test& tmp) {
return _year = tmp._year
&& _month == tmp._month
&& _hour == tmp._hour;
}
//重载赋值运算符
//赋值运算符只能重载为类的成员函数
//无法重载为全局函数
//返回类型为Test&,有返回值是为了支持连续赋值
Test& operator=(const Test& tmp) {
//检查是否自己给自己赋值
if (this != &tmp) {
_year = tmp._year;
_month = tmp._month;
_hour = tmp._hour;
_p = new int(0);
}
return *this;
}
//前置++重载:
Test& operator++() {
_year += 1;
_month += 1;
_hour += 1;
return *this;
}
//后置++重载:
//为了区分,多加一个int传参
Test& operator++(int) {
Test tmp(*this);//调用复制拷贝函数
_year += 1;
_month += 1;
_hour += 1;
return tmp;
}
//const 修饰的成员函数:修饰this指针,无法对类的任何成员进行修改
void Display()const {
cout << _year << '-' << _month << '-' << _hour << endl;
}
private:
int* _p;
int _year;
int _month;
int _hour;
};
//类的对象初始化
//上面提到的是构造函数赋初值
//下面的是构造函数初始化
class A {
public:
//初始化
//类中包含以下成员,必须放在初始化列表位置进行初始化:
// 引用成员变量 int& a
// const成员变量 const int a
// 自定义类型成员变量(且该类无默认构造函数) Test a
//初始化列表中的初始化顺序为成员变量在类中的声明顺序
/*A(int year, int month, int day)
:_year(year)
,_month(month)
,_day(day)
{}*/
//explicit关键字
//单参构造函数:无explicit修饰时,具有类型转换作用
//explicit禁止类型转换
explicit A(int year)
:_year(year)
{}
A& operator=(const A& tmp) {
if (&tmp != this) {
_year = tmp._year;
_month = tmp._month;
_day = tmp._day;
}
return *this;
}
private:
int _year;
int _month;
int _day;
};
//
//
//
//
//类的静态成员
//static 修饰的成员变量——静态成员变量
//static 修饰的成员函数——静态成员函数
//静态成员变量需要在类外定义,定义时不添加static关键字,进行初始化
//静态成员被所有类的对象共享
//静态成员函数没有隐藏的this指针,不能访问任何非静态成员
//静态成员也受pulic,protected,private访问限定符的限制
class B {
public:
B() {
++_b;
}
B(const B& tmp) {
++_b;
}
~B() {
--_b;
}
static int GetACount() {
return _b;
}
private:
static int _b;
};
int B::_b = 0;
void testb() {
cout << B::GetACount() << endl;
B b1, b2;
B b3(b1);
cout << B::GetACount() << endl;
}
//
//
//
//
//友元函数
//通常情况下,类外定义的函数无法访问类内的私有成员
//但可以通过在类内定义这个类外函数为友元函数,即可让其访问自己的自由成员
//友元类同理
class C;
class D;
void show(C& c);
class C {
friend void show(C& c);//加为友元函数
friend class D;
public:
int _c;
C(int a,int b,int c)
:_a(a)
,_b(b)
,_c(c)
{}
private:
int _a;
int _b;
};
class D {
public:
void show(C& c) {
cout << "友元类" << endl << c._a << endl << c._b << endl << c._c << endl;
}
};
void show(C& c) {
cout <<"友元函数"<<endl<< c._c << endl << c._a << endl << c._b << endl;
}
//
//
//
//
//函数模版
//函数模版格式
//template<typename T1,typename T2,......typename T1>
//返回值类型 函数名(参数列表){}
//例子:
template<typename T>
void swap(T& a, T& b) {
T tmp = a;
a = b;
b = tmp;
}
//这里输入的a和b需要同时为一种类型,若为不同类型,会出错
//当需要输入不同类型的a,b时,有两种方法
//1.输入自己进行强制转化
//int a, double b
//swap((double)a,b);
//使用显式实例化
//swap<double>(a,b)
//此时,编译自己会对a进行隐式转换
//非模版函数可以与同名的模版函数同时存在
void swap(int& a, int& b) {
int tmp = a;
a = b;
b = tmp;
}
//当参数类型完全匹配时,优先调用非模版函数
//
//
//
//类模版
//template<typename T1,typename T2,......typename Tn>
//class 类名{
//类内定义
//};
//类模版中函数放在类外进行定义时,需要加模版参数列表
template<typename T>
class E {
public:
~E();
private:
int _a;
int _b;
};
template<class T>
E<T>::~E() {
_a = _b = 0;
}
//类模版实例化:
E<int> e;
int main() {
return 0;
}