JN-PDD

导航

类的六个默认成员函数

构造、析构、拷贝构造、赋值运算符重载、取地址操作符重载、const修饰的取地址操作符重载
(1).构造函数:为对象分配空间、进行初始化(初始化列表、构造函数函数体内赋值)   
class Date
{
public:
     Date()
     {
          _iYear=2016;
          _iMonth=1;
          _iDay=1;
     }
     Date(const int Year=1990,const int Month=1,const int Day=1)
     {
          _iYear=Year;
          _iMonth=Month;
          _iDay=Day;
     }
public:
     int _iYear;
     int _iMonth;
     int _iDay;
};
***全缺省的构造函数和无参的构造函数只能有一个,否则调用的时候就会产生冲突
(2).析构函数:
特点:无参数无返回值(但有this指针)
class Date
{
public:
     Date()
     {
          _iYear=2016;
          _iMonth=1;
          _iDay=1;
          cout<<"this:"<<this<<endl;
     }
     //Date(const int Year=1990,const int Month=1,const int Day=1)
     //{
     //   _iYear=Year;
     //   _iMonth=Month;
     //   _iDay=Day;
     //}
     ~Date()
     {
          cout<<"this:"<<this<<endl;
     }
public:
     int _iYear;
     int _iMonth;
     int _iDay;
};
int main()
{
     Date d,d1,d2,d3,d4;
     return 0;
}

 

*** 对象生命周期结束后,后构造的对象先释放
(3).拷贝构造:用已有对象创建一个新的对象
***浅拷贝:只是值的拷贝的拷贝方式
class Person
{
public:
     Person(char* name,int age)
     {
          m_name=(char*)malloc(sizeof(char)*10);
          if(NULL==m_name)
          {
              cout<<"out of memort"<<endl;
              exit(1);
          }
          strcpy(m_name,name);
          m_age=age;
     }
     ~Person()
     {
          free(m_name);
          m_name=NULL;
     }
private:
     char* m_name;
     int m_age;
};
int main()
{
     Person p1("zhang",20);
     Person p2(p1);
     return 0;
}
***p1 p2指向同一块内存空间;析构的时候p2的this先释放了这段空间,p1就成为野指针,程序会出现bug
***深拷贝:为对象重新分配空间,然后将值拷贝
Person(const Person &p)
     {
          m_name=new char[strlen(p.m_name)+1];
          if(NULL!=m_name)
          {
              strcpy(m_name,p.m_name);
              m_age=p.m_age;
          }
     }
(4).赋值运算符的重载:它是两个已有对象一个给另一个赋值的过程
     默认的赋值运算符重载函数实现的是数据成员的逐一赋值的方法,是一种浅拷贝
***浅拷贝会导致指针悬挂的问题:
class Person
{
public:
     Person(char* name,int age)
     {
          m_name=(char*)malloc(sizeof(char)*10);
          if(NULL==m_name)
          {
              cout<<"out of memort"<<endl;
              exit(1);
          }
          strcpy(m_name,name);
          m_age=age;
     }
     ~Person()
     {
          free(m_name);
          m_name=NULL;
          cout<<this<<endl;
     }
private:
     char* m_name;
     int m_age;
};
int main()
{
     Person p1("zhang",20);
     Person p2("xiao",10);
     p2=p1;
     return 0;
}
p2=p1;两个对象的this指向同一块空间;p2析构后,p1的指针就形成悬挂
 
***通过深层拷贝解决指针悬挂的问题:
Person& operator=(const Person &p)
     {
          if(this==&p)
              return *this;
          delete[]m_name;
          m_name=new char[strlen(p.m_name)+1];
          strcpy(m_name,p.m_name);
          m_age=p.m_age;
          return *this;
     }
 
***const成员函数可以访问非const对象的非const数据成员、const数据成员、也可以访问const对象内的所有数据成员
***非const成员函数可以访问非const对象的非const数据成员、const数据成员、但不可以访问const对象的任意数据成员
***作为一种良好的变成风格,在生命一个成员函数时,若该成员函数并不对数据成员进行修改操作,应尽可能的将该数据成员声明为const成员函数

posted on 2017-03-24 23:42  JN-PDD  阅读(554)  评论(0编辑  收藏  举报