构造函数与析构函数
1.构造函数
1.1 定义:与类同名的成员函数是构造函数,在该类的对象被创建时,自动被调用。
//在类中构造函数
#include<iostream>
using namespace std;
class information{
public:
information()
{
weight=100;
high=180;
cout<<weight<<" "<<high<<endl;
}
protected:
int weight;
int high;
};
void fn()
{
information xiaoming;//自动调用information(),创建对象并初始化
}
int main()
{
fn();
return 0;
}
//在类外构造函数
#include<iostream>
using namespace std;
class information{
public:
information();
protected:
int weight;
int high;
};
information::information()
{
{
weight=100;
high=180;
cout<<weight<<" "<<high<<endl;
}
}
void fn()
{
information xiaoming;
}
int main()
{
fn();
return 0;
}
注意:构造函数没有返回类型,所以函数体内不允许出现返回值,但可以出现无值返回语句"return;"又因为构造函数专门用于创建对象和为其初始化,所以它不能随意被调用。
1.2带参数的构造函数
::可以有多个参数
#include<iostream>
#include<string.h>
using namespace std;
class information
{
public:
information(char *pname)
{
cout<<"constructing information"<<pname<<endl;
strncpy(name,pname,sizeof(name));
//char *strncpy(char *dest, const char *src, size_t n) 把 src 所指向的字符串
//复制到 dest,最多复制 n 个字符。当 src 的长度小于 n 时,dest 的剩余部分将用空字节填充。
name[sizeof(name)-1]='\0';
}
~information()
{
cout<<"destructing"<<name<<endl;
}
protected:
char name[20];
};
int main()
{
information ss("lifang");
return 0;
}
1.3重载构造函数
构造函数可以被重载。
::构造函数是用来创建对象的,不能用来给对象赋值。
#include<iostream>
#include<string.h>
using namespace std;
class date
{
public:
date(int m=4,int d=15,int y=1995)
{
month=m;
day=d;
year=y;
cout<<month<<"/"<<day<<"/"<<year<<endl;
}
protected:
int month;
int day;
int year;
};
int main()
{
date aday;
date bday(2);
date cady(3,2);
date dday(1,2,1995);
return 0;
}
::只有默认了之后才能重载,若有多个默认会造成错误
#include<iostream>
#include<string.h>
using namespace std;
class date
{
public:
date(int m)
{
month=m;
day=2;
year=1995;
cout<<month<<"/"<<day<<"/"<<year<<endl;
}
date(int m,int d=15)
{
month=m;
day=d;
year=1997;
cout<<month<<"/"<<day<<"/"<<year<<endl;
}//其他公共成员
protected:
int month;
int day;
int year;
};
int main()
{
date bday(2);//error,未知匹配哪个构造函数
return 0;
}
1.4 默认构造函数
1. C++规定,每个类必须有一个构造函数,没有构造函数,就不能创建任何对象。
2. 若未提供一个类的构造函数,则C++提供一个默认的构造函数(无参构造函数),仅负责创造对象,不做任何初始化操作。
3. 只要类定义了构造函数,则不提供默认的构造函数,即若定义了一个函数,若需要无参构造函数,需要自己定义。
4. 与变量定义类似,在用默认构造函数创造对象时,如果创造的时全局对象或者时静态对象,则对象的位模式全为0,否则,对象是随机的。
#include<iostream>
using namespace std;
class student{
protected:
char name[20];
};
int main()
{
student noname;//ok:noname的内容为随机值
return 0;
}
//定义类等价于:
class student{
public:
student(){}
protected:
char name[20];
};
::应当对一下情况区别:
#include<iostream>
#include<string.h>
using namespace std;
class information
{
public:
information(char *pname)
{
cout<<"constructing information"<<pname<<endl;
strncpy(name,pname,sizeof(name));
name[sizeof(name)-1]='\0';
}
/*加上:
information(){};
即可*/
protected:
char name[20];
};
int main()
{
information ss;//error,无匹配的构造函数
information ss("lifang");//ok
return 0;
}
1.5 构造类成员
#include<iostream>
using namespace std;
class student
{
public:
student()
{
cout<<"constructing student.\n";
semeshour=100;
gpa=3.5;
}
protected:
int semeshour;
int gpa;
};
class teacher
{
public:
teacher()
{
cout<<"constructing teacher.\n";
}
};
class tutorpair
{
public:
tutorpair()
{
cout<<"constructing tutorpair.\n";
nomeetings=0;
}
protected:
student s;
teacher t;
int nomeetings;//会晤次数
};
int main()
{
tutorpair tp;
cout<<"back in main.\n";
}
每个类负责自己的对象。
2. 析构函数
如果构造函数打开了一个文件夹,就需要关闭该文件夹;或者如果构造函数从堆中分配了内存,这块内存在对象消失前就必须需要被释放。析构函数允许类自动完成这些清理操作,而不必调用其他成员函数。
定义:析构函数也是特殊的类成员函数,无返回类型,没有参数,不能随意调用,也没有重载,只是在类对象生命期结束的时候系统自动调用。
//定义一个析构函数
class x
{
public:
x()
{
name=new char[20]//分配堆空间
}
~x()
{
delete name;//释放堆空间
}
protected:
char *name;
};
当主函数运行到花括号处,析构函数一次被调用。其顺序正好与构造函数相反。
ps:本文是学习笔记,内容来自清华大学出版社出版的C++程序设计教程(修订版)——设计思想与实现。钱能著。