以
class Point {
private:
int x;
int y;
}
为例;
构造函数
/*
<类名>::<类名>(<形参表>){
<函数体>
}
*/
例
Point::Point(){
}
特点
1.被声明为共有(public)
2.函数名与类名相同
3.可以重载
4.不能指定返回类型
5.创建对象时自动调用
构造函数的重载
例如,可以同时定义
Point::Point(){
cout<<"这是一个不带参数的构造函数"<<endl;
}
和
Point::Point(int a,int b){
x=a;
y=b;
cout<<"这是一个带有两个参数的构造函数"<<endl;
}
默认构造函数
当没有为一个类定义任何构造函数时,编译器会自动生成一个无参数,空函数体的默认构造函数
注:
当定义了Point::Point(int a,int b)
,而没有定义Point::Point()
时,如果像Point p1;
这样创建变量就会报错,因为没有合适的构造函数
当二者都没有定义时,再用相同方法创建变量反而不会报错,这是因为编译器自动生成了默认构造函数
带默认参数的构造函数
和带默认参数的其他函数类似
Point::Point(int a,int b){
x=a,
y=b;
}
注意:此时如果定义了默认构造函数并调用Point p1;
则会产生歧义
成员初始化表
/*
<类名>::<构造函数名>(<参数表>):<成员初始化表>{
<构造函数体>
}
*/
成员初始化表的格式为
//数据成员名1(初始值1),数据成员2(初始值2)
例
Point::Point() :x(0),y(0)
{
}
成员初始化表可以给引用或const类型变量赋值,且这两种必须使用成员初始化表赋值
例如,可以在类里定义一个int& rx=x
使用
Point::Point(int x1) :x(x1),rx(x)
{
}
进行初始化
const类型同理
析构函数
/*
<类名>::~<类名>(){
}
*/
例
Point::~Point(){
}
特点
1.被声明为共有(public)
2.函数名与类名相同,但函数名前要加'~'(没有单引号)
3.没有参数,不能重载,一个类里面只能有一个析构函数
4.不能指定返回类型
5.释放对象时自动调用
拷贝构造函数
/*
<类名>::<类名>(const <类名>&<对象名>){
<函数体>
}
*/
例
Point::Point(const Point& p) {
x = p.x;
y = p.y;
}
*拷贝构造函数只有一个参数,该参数是该类对象的引用
如果一个类没有定义拷贝构造函数,则会生成默认拷贝构造函数(将已知对象的所有数据成员的值拷贝给另外一个对象相对应的所有数据成员)
自动调用
1.当用类的一个对象去初始化该类的另一个对象时
2.当函数的形参是类的对象,进行形参和实参结合时
3.当函数的返回值是类的对象,函数执行完成返回调用者时
Point test(Point temp){ //情况2的用法,相当于Point temp = p2
point p(temp) //情况1的用法
return p; //情况3的用法,创建临时对象把值传给p1
}
Point p1,p2(1,1);
p1 = test(p2);
浅拷贝和深拷贝
浅拷贝
使用默认拷贝构造函数实现数据成员的一一赋值
深拷贝
自己写拷贝构造函数的内容,实现额外的内容
如果一个类中含有指针类型的变量,浅拷贝将会发生一些错误
此时不同对象的指针将会指向同一个空间,释放对象时,这个空间也会被多次释放,于是就会报错
如果有不对的地方,欢迎大家指出