一.构造函数的重载:也就是构造函数的函数名相同,而参数的类型或者参数的个数不相同。这里之前已经介绍了。
#include "test1.h"
#include "iostream"
using namespace std;
class Box
{
public:
Box();
Box(int l,int w,int h):length(l),width(w),height(h) {}
int volume();
private:
int length;
int width;
int height;
};
Box::Box()
{
length=10;
width=10;
height=10;
}
int Box::volume()
{
return length*width*height;
}
int main()
{
Box box1;
cout<<"The volume of box2 is:"<<box1.volume()<<endl;
Box box2(15,30,25);
cout<<"The volume of box2 is:"<<box2.volume()<<endl;
system("PAUSE");
return 0;
}
说明:
Box box1;----->调用无参Box::Box();
Box box2(15,30,25);----->调用有参Box:Box(int h,int w,int len);
其中有参的构造函数采用了初始化表的方式。前者位于函数参数表之后,函数体{}之前,后者位于类的实现部分,两者相等。
下面再简单说明一下普通函数的重载:
int max(int x,int y);
int max(int z,int w); //错误。同一函数定义两次。参数表的比较过程跟参数名无关。
int max(int ,int ); //同上。只不过省略了形参
int max(float x,float y); //同上
unsigned int max(int x,int y); //错误。函数值类型也不能够区分两个重载函数
int max(int x,int y,int z); //正确
float max(float x,float y); //正确。参数表中参数的个数和类型均可以认为两个函数可以重载
2.带默认参数的构造函数
//-----------------------------------test.h
#ifndef _TEST1_H_
#define _TEST1_H_
class Box
{
public:
Box(int l=10,int w=10,int h=10);
int volume();
private:
int length;
int width;
int height;
};
#endif
//-----------------------------------test.cpp
#include "test1.h"
#include "iostream"
using namespace std;
Box::Box(int l,int w,int h)
{
length=l;
width=w;
height=h;
}
int Box::volume()
{
return length*width*height;
}
//-----------------------------------mine.cpp
#include "test1.h"
#include "iostream"
using namespace std;
int main()
{
Box box1;
cout<<"The volume of box1 is:"<<box1.volume()<<endl;
Box box2(15);
cout<<"The volume of box2 is:"<<box2.volume()<<endl;
Box box3(15,30);
cout<<"The volume of box3 is:"<<box3.volume()<<endl;
Box box4(15,30,20);
cout<<"The volume of box4 is:"<<box4.volume()<<endl;
system("PAUSE");
return 0;
}
带默认参数的函数说明:
1).定义了带参数的构造函数,那么在定义对象时务必指定实参,如果没有指定实参,则需定义带默认参数的构造函数。C++允许函数参数的值为某些默认值。
如
Box(int l=10,int w=10,int h=10);
在调用时没有指定实参,使用默认值,如给出实参,就以实参为准,且定义对象时可以给出一个或几个实参。
2).在调用时实参取代形参顺序是从左到右,所以在构造函数声明时,非默认形参值只能出现在左边。
如
int add(int x,int y=2,int z=3);
//int add(int x=1,int y,int z=3);错误
//int add(int x=1,int y=2,int z);错误
//同理,上文构造函数声明改成
Box(int l=10,int w,int h=10);
//再
Box box2(15);
cout<<"The volume of box2 is:"<<box2.volume()<<endl;
//就会发生错误,给出原因:缺少参数2的默认参数
3).声明构造函数时,形参可以省略(这个跟一般的函数一样),但定义时还是要带上。
如
//上文构造函数声明可以改成
Box(int =10,int =10,int =10);
//但定义部分不变
4)上文的一个类Box中定义了一个构造函数,且这个构造函数的参数全部是默认参数,这时就不能再定义一个重载构造函数了,否则系统会报错,除非参数值的类型不同。
根据上文,再定义重载构造函数,那就是重复定义了。
warning C4450:'Box':multiple default constructors specifid
error C2668:'Box::Box':ambiguous call to overload function
三.复制构造函数
1.复制对象,也称作给对象赋值.
格式为:
<类名> <对象b> = <对象a>;
其中对象a已经定义,b对a的复制是通过复制a的每个非静态数据成员来实现。
也就是说一个对象a的值可以赋给同类的其他对象b,这里的值是a中所以数据成员的值,不包括静态数据成员。
2.复制构造函数
//声明(类h文件):
<类名> ( <形参表> ); //构造函数的声明
<类名> ( const <类名> & <对象名> ); //复制构造函数的声明
//定义(类cpp文件):
<类名>::<类名> ( const <类名> & <对象名> ); //复制构造函数的实现
复制构造函数是一个特殊的构造函数,具有一般构造函数的的所有特性,不同之处在于形参,这个形参指向类的对象,且引用方式为const .其作用是用一个已经存在的对象去定义同类的一个新的对象。另外复制构造函数只有一个参数,引用的实参只能是本类的对象。
如
//-----------------------------------test.h
#ifndef _TEST1_H_
#define _TEST1_H_
class Box
{
public:
Box(int l=10,int w=10,int h=10);
Box(const Box& b); //复制构造函数在类中的声明
int volume();
private:
int length;
int width;
int height;
};
#endif
//-----------------------------------test.cpp
#include "test1.h"
#include "iostream"
using namespace std;
Box::Box(int l,int w,int h)
{
length=l;
width=w;
height=h;
}
Box::Box(const Box& b) //复制构造函数的实现
{
length=b.length;
width=b.width;
height=b.height;
}
int Box::volume()
{
return length*width*height;
}
//-----------------------------------mine.cpp
#include "test1.h"
#include "iostream"
using namespace std;
int main()
{
Box box1;
cout<<"The volume of box1 is:"<<box1.volume()<<endl;
Box box2=box1; //对象的复制
cout<<"The volume of box2 is:"<<box2.volume()<<endl;
Box box3(15);
cout<<"The volume of box3 is:"<<box3.volume()<<endl;
Box box4(box3); //系统自动调用复制构造函数创建对象box4,并用box3对其进行初始化
cout<<"The volume of box4 is:"<<box4.volume()<<endl;
system("PAUSE");
return 0;
}
四.小结
构造函数和析构函数全部定义为公有成员。
每个类只有一个析构函数,但可以有多个构造函数,这些构造函数包括:
A(); //无参构造函数,用户自定义,带函数体,可以初始化,比如说为0
A(int等); //有参构造函数(含默认参数构造函数)
A(const A& a); //复制构造函数
若类中没有上述显式的构造函数,也就是说用户没有定义,则类A能自动生成默认的无参构造函数和默认的复制构造函数,默认的析构函数同样。如下:
1)默认的无参构造函数:只能声明(创建)对象,但不进行初始化操作.这是和用户自定义的无参构造函数的区别。
2)默认的复制构造函数
3)默认的析构函数