构造函数

一.构造函数的重载:也就是构造函数的函数名相同,而参数的类型或者参数的个数不相同。这里之前已经介绍了。

#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)默认的析构函数

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值