• 类的六个默认成员函数


    构造、析构、拷贝构造、赋值运算符重载、取地址操作符重载、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成员函数
    安心下来做技术,笑是最大的福气
  • 相关阅读:
    CentOS7安装minio
    xshell连接虚拟机Connection failed
    Mysql时间加减函数
    mysql存储过程模板
    Activiti实现会签功能
    2018考研复试流程
    C编程经验总结5(剧终)
    《数据结构总结》
    《关于安卓和IOS开发》
    番外特别篇之 为什么我不建议你直接使用UIImage传值?--从一个诡异的相册九图连读崩溃bug谈起
  • 原文地址:https://www.cnblogs.com/JN-PDD/p/6613972.html
Copyright © 2020-2023  润新知