accelerated c++ 读书笔记--第十一章

1 定义一个向量类最基本需要begin、end、size这三个中的两个。

2 定义: template  class vec{ }

   实体化:vec  v; 声明,这里T就是int

3 new T[n]不仅动态分配内存,且还会用 T构造函数进行默认初始化;

   上述实体化只有T具有默认构造函数时才有vec 

4 库函数提供一些内存分配类,可以直接进行内存分配管理,可以取代new,delete,避免了对构造函数的需要

   在自定义向量类中可以将其实体化为内存管理函数,为private类型

5  构造函数有三种:空的、只有大小的 、有大小和初始值的

    1  vec(){create();}默认构造函数,空vec类,这里调用create成员函数来清空,首末指针都设置成空指针

    2  explicit vec(size_type n,const T& val=T() )  {create(n,val);}

       explicit 用来定义带一个参数的构造函数,只有显式使用构造函数时才会有效

           

        2 中有两个构造函数,一个是size_t类型变量做参数的构造函数

                                            一个是size_t和const T&类型变量做参数的构造函数

        create为n个类型对象T 分配空间,并赋予初值val,但是初始值必须显式使用,否则T默认构造函数来初始化

6 自定义类型中需要用typedef来定义iterator、const_iterator、size_type、value_type

    其中value_type就是内部数据类型,back_inserter由push_back和value_type共同决定。

7 自定义类中,定义索引,T&表示索引 ,T*表示迭代器,这两者都需要定义const和非const两种,begin,end迭代器也需要两种,根据vec类是否是常量来进行选择。

   

复制:隐式即作为参数;

              显式即赋值;

   隐显复制操作都是由copy constructor复制构造函数完成。

  复制构造函数与类名同名的成员函数,复制给同类新对象初始化,只有一个参数,参数与定义类同类型。


  多加了后面的create是为了重新建立一个内存防止复制的新对象,否则在一个内存中,一改全改

9 赋值:赋值运算符也属于成员函数,需要返回值,属于public,重点考虑自我赋值的问题

   声明:vec&  operator=(const  vec&);

   定义:template  

              vec&  operator = (const vec& rts)

              {   if(&rts !=this){

                   uncreate();//如果不同,释放对象占用的旧内存空间

                   create(rts.begin(),rts.end());}

                   return *this;

               } 

   使用:vec::operator=...,使用时写一次就可以了

  注:声明中表明了const,在定义时可不写。

          this只在成员函数内部有效,是指向操作对象的指针,对于二元操作符,this总是指左操作数。

10 注意赋值和初始化的区别:

     初始化:1 声明一个变量:string y;

                    2 在一个函数入口处用到函数参数的时候:plit(words);

                    3 函数返回中使用函数返回值: v =plit(words);这里还包含了赋值

                    4 在构造初始化时:string s="abdjvkg";

     赋值:“=”出现在表达式中,y=words;

     最大的区别:赋值需要清空左操作符的值,释放空间,而初始化不用;

     注:构造函数只控制初始化操作,operator=操作只控制赋值操作;

11 析构函数destructor:名字:~+类名,没有参数,没有返回值

                             public声明:~vec(){uncreate();}

    析构函数删除一个指针变量时不会删除指针所指对象的内存。

12 如果自己定义的类没有给赋值运算符函数和析构函数,那么系统会默认自动生成一个版本。默认的操作会根据数据成员或成员函数原本的规则来进行操作。

13 如果类中没有定义任何构造函数,编译器将自动给予一个没有参数的构造函数。最好的定义类时定义一个默认的构造函数,可以显式也可隐式。

14 “三位一体”规则:构造一个类,如果需要一个析构函数,也就可能需要一个复制构造函数和赋值运算符函数。这三个函数统称为内存管理函数。

15  push_back成员函数:系统会重新分配给现在内存两倍的空间,push_back需要grow(),unchecked_append() 两个函数,且这两个函数不用自己写。

      public:

      void  push_back(const T& val)

      { if(avail==limit)

          grow();

         unchecked_append(val);

      } 

     private:

     iterator  data;

     iterator  avail;

     iterator  limit;

16 内存管理:不采用new和delete,因为受限制很多

     自定义类,采用中有allcator类来分配内存,为类型T分配未初始化的内存,并返回一个指向内存快首元素的指针。自己可以控制,但是标准库也提供删除这种内存块的工具,但是不释放内存。

    tempale

    class allocator{

     public:

     T*      allocate(size_t);  //为T分配内存,返回一个指针

     void   deallocate(T*,size_t);   //释放内存,参数:指针,内存大小

     void   construct(T*,T);   //初始化生成单个对象T

     void   destory(T*);    //删除参数所指对象;

     };

     void   uninitialized_fill(T*,T*,const T&);   // 向12区间填充3的对象,相当于初始化

     void   uninitialized_copy(T*,T*,T*);   //将12区间的内容复制到3所指的内存块中,返回3结尾的指针

17 类不变式:(定义类必须满足的条件)

             

18 create函数是为了分配内存,并初始化,以及正确的设置指针。

     uccreate是删除对象,释放内存。

19 delete作用于空指针也可以,但是alloc.deallote需要非零指针做参数

20 标准库类型(library type)ptrdiff_t 与 size_t 类型一样,ptrdiff_t 也是一种与机器相关的类型,在 cstddef 头文件中定义。size_t 是unsigned 类型,而 ptrdiff_t 则是 signed 整型

21 自定义的类,在类限定的范围内可以直接使用,但是超出类范围需要加类的限定词;

22 创建和复制对象时会调用构造函数

23 只有没有定义任何构造函数,编译器才会自动生成一个不带任何参数的构造函数。

24 赋值会先删除原内存单元的值,然后在赋予其新的值。

    具体的操作为:自动调用string和vector的复制构造函数对name和homework进行赋值;直接对两个double变量midterm和fin进行赋值;

    无论是复制还是赋值,对于string和vector的需要调用复制构造函数,但是double、int等内部类型可以直接复制和赋值

25 习题11-4,析构函数删除了内容但是没有释放内存,只是删除了Student_info中的name,midterm,fainter,homework四个成员函数

26 一个自定义类成分;

    public://迭代器(const两)+size_type+value_type 

                 //构造函数+赋值、复制、析构函数、索引、begin、end、size、push_back

    private:数据元素、内存分配工具、create、uncreate、grow、unchecked_append

27 vector:数组实现;顺序存储结构,采用预分配策略分配内存;可随机访问元素所以利用索引实现元素访问;仅支持后插故只实现push_back();

list:双向链表实现;采用链式存储结构,不需要预分配;不支持随机访问即不支持索引,利用迭代器++和--以实现遍历;支持前插push_fron()和后插push_back()以及insert()等操作;




你可能感兴趣的:(c++学习)