您的位置:首页 > 其它

day05 this指针和常函数、析构函数(Destructor) 、拷贝构造和拷贝赋值

2017-06-17 22:29 162 查看
回顾:

1 构造函数

  类名(...){初始化成员变量}

2 类声明放在".h";类的实现放在".cpp"

3 对象的创建和销毁

eg:

class A{..};

A a;//A a = A()

A a(构造实参);//A a = A(构造实参)

---------

A* pa = new A;

A* pa = new A(构造实参);

 

十四 构造函数和初始化表

1 构造函数可以重载

2 缺省无参构造函数

3 类型转换构造函数(explicit)

4 拷贝构造函数

=================

今天

5 初始化表

1)用于初始化类中的成员变量

语法:

   class 类名{

      类名(形参表):成员变量(初值),...{

           函数体;

      }

   };

eg:

class A{

public:

  A(void):m_i(0),m_j(0){}

  A(int i,int j):m_i(i),m_j(j){

     m_i = i;

     m_j = j;  

  }

  int m_i;

  int m_j;

};

 
2)必须要使用初始化表的场景

-->如果类中有类 类型的成员变量,而该类又没有无参构造函数,则必须使用初始化表指定该成员子对象的构造实参。

-->如果类中包含"const"和"引用&"成员变量,必须使用初始化表来初始化

 

练习:用初始化表为电子时钟类增加计时器的功能,如果使用日历时间构造对象,表现为时钟;如果使用无参构造的方式构造对象,通过初始化表将时分秒初始化为0:0:0,表现为计时器。

 
注:成员变量的初始化顺序由声明顺序所决定,而与初始化表的顺序无关

 

十五 this指针和常函数

1 this指针

1)类的构造函数和成员函数都隐藏一个该类类型的指针参数,名字为this。在构造函数或者成员中访问该类的其它成员,都是通过this指针进行的

2)对于普通成员函数,this指针就指向调用该函数的对象

3)对于构造函数,this指针指向正在被构造的的对象

 
4)需要显示使用this指针的场景

--》区分作用域

--》从成员函数中返回调用对象的自身(返回自引用)

--》从类的内部销毁该对象自身

 

2 常函数

1)在一个成员函数的参数表后面加上const,这个函数就称为常函数。

  返回类型  函数名(形参表)const{函数体}

2)常函数中this指针是一个常指针,不能在常函数中修改成员变量的值

 
注:mutable关键字,用于修饰一个成员变量,修饰以后该成员变量可以在常函数被修改。

 

4)非 常对象既可以调用常函数也可以调用非常函数,但是常对象只能调用常函数,不能调用非常函数。

 

注:常对象也包括常引用、常指针

 
5)函数名和形参表相同的成员函数,其常版本和非常版本可以构成重载关系,常对象调用常版本,非常对象调用非常版本。

---------------------

十六 析构函数(Destructor)

1 语法形式

class 类名{

public:

   ~类名(void){...}//析构函数

};
1)析构函数是类中特殊的成员函数,名字“~类名”

2)没有返回类型,也没有参数,不能被重载,一个类只能有一个析构函数。

3)主要负责清理对象在构造时所分配的动态资源

 

2 当对象被销毁时,该对象的析构函数将被自动调用

1)栈对象离开作用域时,析构函数被"}"调用

2)堆对象,被delete/delete[]运算符调用

 

3 如果一个类没有显式定义析构函数,那么编译器会为该类提供缺省的析构函数

1)对基类类型成员变量,什么也不做

2)对类 类型的成员变量,调用相应类的析构函数来析构成员子对象。

 
4 对象的创建和销毁的过程

1)对象的创建

--》分配内存

--》调用成员子对象的构造函数

--》执行构造函数代码

 

2)对象销毁

--》执行析构函数代码

--》调用成员子对象的析构函数

--》释放内存

 

十七 拷贝构造和拷贝赋值

1 浅拷贝和深拷贝问题

   如果一个类包含指针形式的成员变量,缺省的拷贝构造函数只是复制指针变量本身,而没有复制该指针所指向的内容,这种拷贝方式称为浅拷贝;

   浅拷贝将导致不同对象间的数据共享,在delete时会引发"double free"异常。因此必须自己定义一个支持复制指针所指向内容的拷贝构造函数,即深拷贝。

   //参考copy.jpg

 

练习:实现String类

class String{

public:

   //构造函数

   String(const char* str=""):

      m_str(strcpy(new char[strlen(str)+1],str)){}    

   //析构函数

   //深拷贝构造函数

 

   const char* c_str(void)const{

    return m_str;

   }

private:

  char* m_str;

};

int main(void)

{

   String s1("hello world");

   String s2(s1);//拷贝构造

   cout << s1 << endl;//hello world

   cout << s2 << endl;//hello world

}

 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐