构造函数用来为对象分配内存空间及初始化赋值
析构函数用来释放分配给对象的内存空间。
构造函数
构造函数的作用:
(1)为对象分配空间并初始化
(2)对数据成员赋值
(3)请求其他资源
构造函数的名字与类名相同,不能任意命名,构造函数不具有类型,无返回值。
语法:构造函数名(形参):初始化列表
{
函数体
}
Clock(int h,int m,int s):hour(h),minute(m){
second = s;
}
关于初始化列表注意以下几点:
(1)数组成员不能在初始化列表中初始化
(2)static数据成员不能在初始化列表中初始化
(3)非static的const数据成员必须在初始化列表中初始化
调用构造函数的格式:
类名 对象名(实参列表);
类名 *对象名 = new 类名(实参列表)
#include<iostream>
using namespace std;
class Point{
private:
double x,y;
public:
Point(double a=0.0,double b=0.0); //构造函数
void disp();
};
Point::Point(double a,double b){
x=a;
y=b;
}
void Point::disp(){
cout<<x<<","<<y<<endl;
}
int main(){
Point p1(1.0,2.0),p2(3.0),p3;
cout<<"p1=";
p1.disp();
cout<<"p2=";
p2.disp();
cout<<"p3=";
p3.disp();
return 0;
}
析构函数
在类中定义的析构函数,在对象生命周期结束时自动执行,完成清理内存的工作,并可以执行指定的其他操作。
一个类中只能定义一个析构函数。
析构函数由名由破折号“~”与类名组合而成,析构函数不接受参数(所以不能重载,只有一个析构函数),没有返回值。
//析构函数语法
class 类名
{
public:
.
.
.
~类名()
{指定的操作;}
};
//例如
class Clock
{
private:
int hour,minute,second;
public:
Clock(int h,int m,int s){ //构造函数
hour = h;
minute = m;
second =s;
}
~Clock(){ //析构函数
cout<<"destructing";
}
void Clock::showClock(){
cout<<hour<<minute<<second;
}
};
拷贝构造函数
构造函数是当定义一个新对象时自动调用的函数,是一个从无到有的过程,但是拷贝构造函数需要利用一个已经存在的对象再生成一个新的对象,也就是由原有的对象拷贝生成一个新的对象。
//拷贝构造函数
Point p1("home",1.0,2.0);
Point p2 = p1;
对象p1生成时没有参照任何现有对象,而对象p2生成时是参照p1生成的,也称作p1初始化p2。浅拷贝深拷贝
1,浅拷贝就是对象数据之间的一一赋值。只是浅层次的复制对象空间,并未将堆空间的东西拷贝。
当浅拷贝时,两个对象就有共同的资源,可以同时对资源进行访问,这样就可能会出现问题。
2,深拷贝就是来解决公 用资源问题的,他把资源也拷贝一份,使生成对象拥有和原对象不同的资源,但是资源的内容是一样的。对于堆资源来说就是再开辟一片堆内存,把原来的堆内容也拷贝到新开辟的堆内存,这就是深层次的拷贝,因此叫深拷贝。
对象数组
//计算一组学生的总成绩和平均值
#include<iostream>
#include<cstring>
using namespace std;
class Student{
private:
char name[20];
int age;
float score;
public:
Student(char *n,int a,int s){
strcpy(name,n);
age = a;
score =s;
}
float getScore(){
return score;
}
};
int main(){
Student stud[3] = {Student("zhang san",20,60),Student("Li si",19,70),Student("wang wu",18,78)};
float sum=0,average;
int i;
for(i=0;i<3;i++){
sum+=stud[i].getScore();
}
average =sum/3;
cout<<"sum="<<sum<<"average="<<average<<endl;
return 0;
}