> 文章列表 > C++类的学习1

C++类的学习1

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,析构函数正好相反;