类的默认成员函数

类有6个默认成员函数:
1.构造函数
2.拷贝构造函数
3.析构函数
4.赋值操作符重载
5.取地址操作符重载
6.const修饰的取地址操作符重载

一:构造函数

作用:对私有成员变量进行初始化。 Date();
公有成员函数,仅在定义对象时自动执行一次。
特点:
1.函数名与类名相同。
2.对象构造时自动调用。
3.无返回值。
4.可以重载。
5.可以在类内外定义。
6.如果无构造函数,编译器自动产生一个缺省的构造函数。
7.无参和全缺省值的构造函数都认为是缺省构造函数,并且缺省构造函数之能有一个。

class Date
{
public:
    Date()  //缺省构造函数
    {};
    Date(int year,int month,int day)//构造函数
    {
        _year=year;
        _month=month;
        _day=day;
    }
private:
    int _year;
    int _month;
    int _day;
};

二:拷贝构造函数

作用:创建对象时使用同类对象来进行初始化。Date(const Date&t)
特点:
1.是构造函数的一个重载。
2.必须使用引用传参,传值会无穷递归调用。
3.未定义时,编译器会自动生成一个默认缺省拷贝构造函数,缺省的拷贝构造函数会依次拷贝类成员进行初始化。
Date d1;
Date d2=d1; 等价
Date d3(d1);

class Date
{
public:
    Date()//构造函数
    {}
    Date(int year,int month,int day) //构造函数
    {
        _year=year;
        _month=month;
        _day=day;
    };
    Date(const Date&t)  //拷贝构造函数
    {
        _year=t._year;
        _month=t._month;
        _day=t._day;    
    }
private:
int _year;
int _month;
int _day;
};

拷贝构造函数必须使用引用传参的原因
使用代码:

class Date
{
public:
    Date()//构造函数
    {}
    Date(int year,int month,int day) //构造函数
    {
        _year=year;
        _month=month;
        _day=day;
    };
    Date(const Date t)  //拷贝构造函数
    {
        _year=t._year;
        _month=t._month;
        _day=t._day;    
    }
private:
int _year;
int _month;
int _day;
};
Funtest()
{
    Date d1(2111,2,2);
    Date d2=d1;
}

Date d2=d1;
调用拷贝构造函数 Date(const Date t); 相当于 d2(d1);
因为传参过程中是值传递,所以需要创建一个临时变量来存放d1的值,假设此时的临时变量名为 d’;
此时要用d1来初始化d’,相当于d’(d1),此时需要调用拷贝构造函数 Date(const Date t);
因为因为传参过程中是值传递,所以需要创建一个临时变量来存放d1的值,假设此时的临时变量名为 d”;此后所有的过程相同,程序将陷入一个无穷递归的过程。
所以拷贝构造函数传参过程中需要引用传参。

一 – 二 :类成员的初始化方式

1.构造函数内进行赋值
2.初始化列表
以一个冒号开始,接着一个逗号分隔数据列表;
Date(…,const Date&t)
:_year(year)
,_month(month)
,_day(day)
{}
其中,成员变量按照声明顺序依次初始化;

必须使用初始化列表的变量:
(1).常量成员变量
(2).引用类型成员变量
(3).没有缺省构造函数的类成员变量

三:析构函数 ~Date()

作用:在对象声明周期结束时,调用的函数。(清除类本身分配的资源);
特点:
1.函数名在类名前加上~;
2.无参数无返回值;
3.一个类只能有一个析构函数,若未定义,系统默认生成析构函数;
4.自动调用;
5.析构函数并非删除对象,而是做一些清理工作(释放空间);

class Array()
{
public:
    ~Array(){  //析构函数  清理工作
        if(_ptr){
            free(_ptr);
            _ptr=0;
        }
    }
private:
    int *_ptr;
}

四.重载:

作用:增强程序的可读性 关键词 :operator
特点:
1.operator+合法的运算符构成函数名;
2.重载运算符,不可以改变,操作数个数,结合性;
3.不能重载的运算符 “*/ ” “:: ” “?: ” “. “;
输入输出运算符的重载:
对于自定义的类,不能直接通过

cout<<Date或cin>>Date;

通过重载输入输出运算符,让自定义的类也支持这样的操作;
friend ostream &operator<<(ostream &os,const Date &stu);
friend istream &operator>>(istream &is,const Daet &stu);
cout并不特殊,是预先定义好了的ostream类的对象
输出运算符重点:
输出运算符的第一个形参时一个非常量(自流写入内容会改变状态)的ostream对象的引用(流对象不支持复制)。
第二个参数一般来说是一个常量(打印不需要改变对象内容)的引用(避免复制实参)。
输出函数应尽量避免格式化的操作。
输入运算符重点:
输入运算符的第一个形参是将要读取的流的引用。
第二个形参是将要读入到的非常量对象的引用。
输入运算符必须处理输入可能失败的情况。(输入数据与类型不匹配)(流达到文件末尾)
声明为友元函数。
输入,输出运算符都必须是非成员函数;

class Date
{
public:
    //构造函数,列表初始化
    Date() 
        :_year(0)
        , _month(0)
        ,_day(0) {}
    //重载输出运算符    
    friend  ostream  &operator<<(ostream &os, const Student &stu);  //声明为友元
                                                                    //重载输入运算符
    friend  istream  &operator >> (istream &is, Student &stu);
private:
    int _year;
    int _month;
    int _day;
};

ostream  &operator<<(ostream &os, const Student &stu)
{
    os << Date._year << " " << Date._month<<" "<<Daet._day;
    return os;
}
istream  &operator >> (istream &is, Student &stu)
{
    is >>Date._year>>Date._month>>Date._day;
    //输入判断
    if (!is)
        stu = Date(); //如果失败,默认初始化
    return is;
}

四.赋值运算符重载

作用: 对一个已存在的对象进行拷贝赋值;
Date &operator = (const Date &d);

class Date()
{
public:
    Date(int year,int month,int day)
        :_year(year)
        ,_month(month)
        ,_day(day)
        {}
    Date &operator(const Date &t){
        if(this!=d){        
            this->_year=d._year;
            this->_month=d._month;
            this->_day=d._day;      
        }
        return *this;
    }
private:
    int _year;
    int _month;
    int _day;
};
FunTest(){
    Date d1(2001,1,1);
    Date d2;
    d2=d1;
}

四–五 :友元
友元函数: 关键词: friend
友元函数可以直接访问类的私有成员,是定义在类外的函数。
友元函数不属于类的成员函数,但需要在类内声明(可以在类内的任何地方声明,所以友元函数不受访问限定符的限制),声明时要加上关键字friend。
友元类:
整个类都可以是另一个类的友元函数,都可访问另一个类中的成员。

class Time
{
friend class Date;
//Date是 Time的友元,所以Date可以访问Time的所有成员 
private:
    int _hour;
    int _minute;
    int _second;
};
class Date
{
public:
    void Display(){
        cout<<"year"<<_year<<endl;
        cout<<"month"<<_month<<endl;
        cout<<"day"<<_day<<endl;
        cout<<"hour"<<_hour<<endl;
        cout<<"minute"<<_minute<<endl;
        cout<<"second"<<_second<<endl;
    }
private:
    int _year;
    int _month;
    int _day;
};

友元关系是单向的,不具有交换性。
友元关系无法传递。
友元关系无法继承。

五.取地址操作符重载 ———- Date * operator&();
六.const修饰的取地址操作符重载;const Date * operator&();
这两个默认成员函数一班不需要重载。

七.const修饰的成员函数
在成员函数后面加上const,用来修饰this指针所指向的对象,保证此对象在函数内不会被改变。
this指针的形式为,const Date *this;
const修饰成员函数后,变为 const Date * const this;

class Date
{
public:
    void SetDate(int yar,int month,int day) const {
        _year=year;
        _month=month;
        _day=day;
    }
private:
    int _year;
    int _month;
    int _day;
};

此时的对象的成员将无法被SetDate()函数更改。

八.类的静态成员
1.static修饰的成员,称为静态类成员。
2.类的静态成员被该类型的所有对象所共享。
3.静态成员函数不会生成this指针,所以可以使用类型::作用域访问符调用静态成员函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值