C++类的学习1
类的定义一般包括两部分,一是类的属性,二是他所拥有的方法。类的实例化是指给类的加载并初始化过程,比如一个people类,我们具体到每一个人就是类的实例化,此外一个类可以在此类上进行扩展。比如people类,我们分为 外国people 和 中国people,那么people叫做基类,外国people叫做派生类或子类
1.C++类的定义
C++使用class关键字定义一个类:
public:公共的行为或属性(类外可以调用);
private:表示该部分内容是私密的,不能被外部访问或调用,只能在类内调用;
protected:保护成员,和私有成员类似,不过在派生类可以调用;
比如我们建立一个people类
#include <iostream>
using namespace std;
class people{public:void a(){cout<<name;}private:string name="小明";void b(){cout<<"dsfsfds"; //不必在意;}
};
int main(){people cao; //实例化cao.a();return 0;
}
类的传参,比如我们要传入人的身高和体重,可以通过一个函数传入,传给私有变量;
#include <iostream>
using namespace std;
class people{public:void a(){cout<<name<<' '<<height<<' '<<weight;}void chuanru(int x,int y){
//x,y是函数内的的变量,因此需要赋值给整个类的变量,作用域不同height=x;weight=y;} private:string name="小明";int height;int weight;
};
int main(){people cao;cao.chuanru(170,130);cao.a();return 0;
}
此外类内的函数或者方法可以放到类外面,需要先在类内声明函数,通过“::”作用域操作符实现例如:
#include <iostream>
using namespace std;
class people{public:void a();void chuanru(int x,int y); //函数声明private:string name="小明";int height;int weight;
}; void people::a(){ //表面是people的a函数cout<<name<<' '<<height<<' '<<weight;}
void people::chuanru(int x,int y){height=x;weight=y;} int main(){people cao;cao.chuanru(170,130);cao.a();return 0;
}
2.初识构造函数和析构函数
先不管那些拷贝构造函数和转换构造函数,我们先学习普通的,
#include <iostream>
using namespace std;
class people{public:people(int x=8,int y=9){ //构造函数,可以设置默认值height=x;weight=y;}void a(){cout<<name<<' '<<height<<' '<<weight;}private:string name="小明";int height;int weight;
};
int main(){people cao(170,130); //构造函数传参,cao.a();return 0;
}
同理构造函数也可以放到类外面
#include <iostream>
using namespace std;
class people{public:people(int x,int y);void a();private:string name="小明";int height;int weight;
}; people::people(int x=9,int y=8){ //类内或类外只能有一个地方初始化height=x;weight=y;}
void people::a(){cout<<name<<' '<<height<<' '<<weight;}int main(){people cao(170,130);cao.a();return 0;
}
构造函数用来初始化类,析构函数与构造函数相反;在对象生命周期结束后自动调用,用于在对象删除之前的清理工作,清理对象释放内存;
#include <iostream>
using namespace std;
class people{public:people(int x,int y);void a();~people();private:string name="小明";int height;int weight;
}; people::people(int x=9,int y=8){height=x;weight=y;}
people::~people(){}
void people::a(){cout<<name<<' '<<height<<' '<<weight;}int main(){people cao(170,130);cao.a();return 0;
}
是生命周期结束,举个例子:
#include <iostream>
using namespace std;
class people{public:people(string n,int x,int y); void a();~people();private:string name;int height;int weight;
}; people::people(string n,int x=9,int y=8){name=n;height=x;weight=y;cout<<name<<' '<<"调用构造函数"<<endl; }
people::~people(){cout<<name<<' '<<"调用析构函数"<<endl;
}
void people::a(){cout<<name<<' '<<height<<' '<<weight<<endl;;}
void shiyan(){people lin("小刚",180,190);
}
int main(){people cao("小明",170,130);shiyan();cout<<"main还没结束!"<<endl; return 0;
}
小明是在main函数内,小刚是在shiyan()函数内,调用完shiyan() 函数后小刚生命周期结束,调用小刚的析构函数,而小明是等到main函数结束后调用析构函数;
其实构造函数还有初始化列表形式:
#include <iostream>
using namespace std;
class people{public:people(int x,int y); //构造函数void a();~people(); //析构函数private:string name="小明";int height;int weight;
}; people::people(int x=9,int y=8):height(x),weight(y){} //初始化列表
people::~people(){}
void people::a(){cout<<name<<' '<<height<<' '<<weight;}int main(){people cao(170,130);cao.a();return 0;
}
想知道构造函数怎样工作的吗?
我来告诉你
首先我们来看定义未知数的顺序;
我们先定义height,在定义weight,那么构造函数是按照先初始化height在初始化weight的顺序构造的,并不是按照构造函数的顺序,举个例子:
#include <iostream>
using namespace std;
class people{public:people(int x);void a();~people();private:string name="小明";int height;int weight;
}; people::people(int x=9):height(x),weight(height){}
//先初始化height,再将height赋值给weight
people::~people(){}
void people::a(){cout<<name<<' '<<height<<' '<<weight;}int main(){people cao(170);cao.a();return 0;
}
#include <iostream>
using namespace std;
class people{public:people(int x);void a();~people();private:string name="小明";int height;int weight;
}; people::people(int x=9):height(weight),weight(x){}
//先初始化height,但height依赖于weight,由于weight没有初始化,所以出现错误;
people::~people(){}
void people::a(){cout<<name<<' '<<height<<' '<<weight;}int main(){people cao(170);cao.a();return 0;
}
3.类的继承
子承父业吗,子类继承父类,分为三种继承方式;
(1)公共继承:父类的公共属性在子类还是公共属性,保护属性还是保护属性,私有属性子类访 问不到
(2)保护继承:父类的公共属性和保护属性在子类中都变为保护属性;私有还是访问不到
(3)私有继承:父类的公共属性在子类变为保护属性,父类的保护属性变为私有属性,私有访问 不到;
举例说明:
(1)公共继承:
#include <iostream>
using namespace std;
class father{public:string a="father 公共";protected:string b="father 保护";private:string c="father 私有";
};class son:public father{public:
// string a="son 公共";
// string b="son 保护";
// c="son 私有"; void dain(){cout<<a<<endl<<b<<endl<<endl;
// cout<<c; //报错 }
};
int main(){son linyuan;linyuan.dain();cout<<linyuan.a<<endl;
// cout<<linyuan.b<<endl; //报错 return 0;
}
(2)保护继承
#include <iostream>
using namespace std;
class father{public:string a="father 公共";protected:string b="father 保护";private:string c="father 私有";
};class son:protected father{public:
// string a="son 公共";
// string b="son 保护";
// c="son 私有"; void dain(){cout<<a<<endl<<b<<endl<<endl;
// cout<<c; //报错 }
};
int main(){son linyuan;linyuan.dain();
// cout<<linyuan.a<<endl;
// cout<<linyuan.b<<endl; //报错 return 0;
}
(3)私有继承
#include <iostream>
using namespace std;
class father{public:string a="father 公共";protected:string b="father 保护";private:string c="father 私有";
};class son:private father{public:
// string a="son 公共";
// string b="son 保护";
// c="son 私有"; void dain(){cout<<a<<endl<<b<<endl<<endl;
// cout<<c; //报错 }
};
int main(){son linyuan;linyuan.dain();
// cout<<linyuan.a<<endl;
// cout<<linyuan.b<<endl; //报错 return 0;
}
那么继承方式讲完了,其实C++类还支持同时继承多个类例如;
#include <iostream>
using namespace std;
class father1{public:string name1;father1(){name1="小刚"; }
};class father2{public:string name1;father2(){name1="小明"; }
};class son:public father1,public father2{public:string name1;son(){name1="木木渊"; }};
int main(){son a;cout<<a.name1<<endl;cout<<a.father1::name1<<endl;cout<<a.father2::name1;}
派生类和父类继承元素重名时可以通过命名空间来分别 ,函数也是如此实现多继承;
接下来我们看一下析构函数的情况;
#include <iostream>
using namespace std;
class father1{public:string name1;father1(){cout<<"father1 构造函数"<<endl; name1="小刚"; }~father1(){cout<<"father1 析构函数"<<endl; }
};class father2{public:string name1;father2(){name1="小明"; cout<<"father2 构造函数"<<endl; }~father2(){cout<<"father2 析构函数"<<endl; }
};class son:public father1,public father2{public:string name1;son(){name1="木木渊"; cout<<"son 构造函数"<<endl;}~son(){cout<<"son 析构函数"<<endl; }};
int main(){son a;cout<<"main 要结束了"<<endl; }
很明显son先继承father1,在继承father2,因此构造函数先是father1,再father2,最后son,析构函数正好相反;