c++类的默认六个成员函数

c++中默认的六个成员函数分别是:构造函数,拷贝构造函数,赋值操作符重载函数,析构函数,取地址操作符重载函数,const修饰的取地址操作符重载函数
一、构造函数:
1,构造函数是一个特殊的成员函数,名字与类同名,创建类类型对象时由编译器自动调用,保证每个数据成员都有一个合适的初始值,并且在对象的生命周期内只调用一次
2,并不是开空间创建对象,而是初始化对象:函数名与类同名,无返回值,对象实例化是编译器自动调用对应的构造函数,构造函数可以重载。
3,无参和全缺省的构造函数都称为默认构造函数,并且默认构造函数只有一个。无参构造函数、全缺省的构造函数,我们没写编译器默认生成的构造函数,都可以认为是默认成员函数。
4,编译器自己生成默认构造函数,这里编译器会给自己生成的构造函数赋随机值。
c++把类型分成内置类型(基本类型)和自定义类型。内置类型就是语法已经定义好的类型:如int/char…,自定义类型就是我们使用class,struct,union自己定义的类型,编译器生成默认的构造函数会对自定类型成员调用它的默认成员函数。
二、拷贝构造函数:

class A
{
private:
int value;
public:
A(int n)
{value=n;}
A(A other)
{other.value:}
}

上面这段代码会出现编译出错,因为传入的参数是一个实例。由于是传值参数,我们把形参复制到实参会调用复制构造函数。如果允许复制构造函数传值,就会在复制构造函数内调用复制构造函数,就会形成永无休止的递归调用从而导致栈溢出。 这里把构造函数修改为A(const A&other),也就是把传值参数改为常引用。
三、赋值操作符重载函数

class mystring
{
public:
mystring(char *pDate=nullptr);
mystring(const mystring& str);
~mystring(void);
private:
char *m_pData;
}

写一个赋值运算符重载函数注意:
1,是否并返回值的类型声明为该类型的引用,并且函数结束前返回实例自身的引用(this)。只有返回一个引用,才可以允许连续赋值。 否则,如果函数的返回值是void,则应用赋值运算符将不能进行连续赋值。
2,是否把传入的参数的类型声明为常量引用。如果传入的参数不是引用是实例,那么从形参到实参会调用一次复制构造函数。把参数声明为引用可以避免这样的无谓消耗,能提高代码的效率。 同时,我们在赋值运算符函数内不会改变传入的实例的状态,因此应该为传入的引用参数加上const关键字。
3,是否释放实例自身已有的内存。如果我们忘记在分配新内存之前释放自身已有的空间,则程序将出现内存泄漏。
4,判断传入的参数和当前的实例(星号this)是不是同一个实例。如果是同一个,则不进行赋值操作,直接返回。如果事先不判断就进行赋值,那么在释放实例自身内存的时候就会导致严重的问题:当(星号this)和传入的参数是同一个实例时,一旦释放了自身的内存,传入的参数的内存也同时被释放了,因此再也找不到需要赋值的内容了。
5、(.
),(:?,(sizeof),(??(.),注意以上5个运算符不能重载。

mystring& mystring::operator=(const mystring &str)
{
if(this!=&str)
{
delete [] m_pData;
m_pData=nullptr;
m_pData=new char[strlen(str.m_pData)+1];
strcpy(m-pData,str.m_pData);
}
return *this;
}

总结:这里两个引用:参数引用避免拷贝开销,返回值引用支持链式开销。
以上这个版本如果此内存不足导致new char抛出异常,则m_pData将是一个空指针,这样非常容易导致程序崩溃。因此,用一个更好的办法就是用一个临时实例和原来的实例进行交换。

mystring& mystring::operator=(const mystring &str)
{
if(this!=&str)
{
//这里strTmp是一个局部变量,但程序运行到if的外面也就是出了该变量的作用域,就会自动调用strTmp的析构函数,把strTmp.m_pData所指向的内存释放掉。
mystring strTmp(str);
char *ptemp=strTmp.m_pData;
strTmp.m_pData=m_pData;
m_pData=ptemp;
}
return *this;
}

四、析构函数
析构函数:与构造函数功能相反,析构函数不是完成对象的销毁,局部对象销毁工作是由编译器完成的。而对象在销毁时会自动调用析构函数,完成类的一些资源清理工作。
(不是删除对象,而是做一些对象删除前的相关清理工作)
特征:1,析构函数名是在类名前加上字符~。2,无参数无返回值。3,一个类有且只有一个析构函数。 若未显示定义,系统会自动生成默认的析构函数。4,对象生命周期结束时,C++编译系统自动调用析构函数。
五、const修饰的取地址操作符重载函数
1、const修饰类的成员函数
将const修饰的类成员函数称之为const成员函数,const修饰类成员函数,实际修饰该成员函数隐含的this指针,表明在该成员函数中不能对类的任何成员进行修改
在成员函数后面加const,const修饰this指针所指向的对象,也就是保证调用这个const成员函数的对象在函数内不会被改变。
2、const对象不能调用非const成员,因为const修饰的this指针,不能被修改
但非const对象可以调用const成员函数。const成员函数内不能调用其它的非const成员函数,因为其权限被扩大。但非const成员函数内可以调用其它的const成员函数。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值