技术2022-05-19  29

    1. 结构体也可以继承,可以有虚函数、构造、析构,与class唯一区别是默认public

    定义结构体变量时struct关键字可省略 (类也一样)

     

    2. 编译器为空类产生4个成员函数   默认构造函数,析构函数,拷贝构造函数,赋值函数

        注意拷贝构造是构造 String c = a;

                           c = a;是赋值   

    即使只定义了有参构造,编译器也不会再产生默认的无参构造

     

    赋值函数

    String & String::operate = (const String &other)

    //返回String& 类型

    //参数要const 否则在右操作数 是const情况下就不能用了

    {

        if(this == &other)   //检查自赋值  否则自赋值会出错

           return *this;

        delete [] m_data;    //注意先释放

        int len = strlen(other.m_data);

        m_data = new char[len+1];

        strcpy(m_data, other.m_data); //strcpy会加上0

        return *this;//返回值是自己

    }

    (运算符重载写法与函数一样,只是函数名为operate =)

     

    3.  对象初始化

    三种初始化方式

    A a(1);     A a = A(1);   A a = 1;必须只有一个参数

    注意 A a();   是声明了一个函数 返回A类型  无参构造就不要()

    A a = 1;属于隐式调用构造函数,构造函数前加explicit可阻止隐式调用

     

    拷贝构造

    A(const A& a){}  可不要const 但一定要& (没有&,则本身也需要拷贝)

    要禁止拷贝可以显式定义private的拷贝构造

     

    构造函数的初始化列表 A():x(1),y(2){};

    作用    需要初始化的数据成员是对象

            需要初始化const修饰的类成员

            需要初始化引用成员数据      

    这三种无法在构造函数里初始化

    对象如果有无参构造,则可以不用在此初始化 

    继承可用此方法初始化父类的private成员

    只有static const的整形数据成员 可以在类定义中初始化

    初始化是按照变量声明顺序,先声明的变量在后面就不会被初始化

     

    默认参数在函数的声明和定义中只能出现一次

     

    类成员函数的const限定符必须在声明和定义时同时指定

     

    4.  继承

    三种继承方式,公保成员对子类都可见,成为子类的公保、保、私成员

    保护成员对类的对象不可见   目的是为了继承可见

    默认是私有继承

     

    各个类的同名变量没有覆盖,各个类的函数所用的变量都是自己的,初始化时各自初始化自己的

        子类要替父类初始化可通过初始化列表:A(1)  

        若子类对象调了父类的函数,父类的函数再调用函数时也是调父类的,当被调函数为虚时才应用动态关联尝试调子类

        若指明调用 c.A::f() 即使虚函数也直接调A

    用父类指针给子类指针赋值,调的仍是父类函数

     

    多态本质就是将子类类型的指针(引用)赋值给父类类型的指针  

    用子类对象给父类对象赋值就不会有多态效果,子类新增成员会丢失

     

    父类函数虚拟,则子类自动成为虚拟,可以不用指明

    子类虚函数的声明必须与父类的声明一致,返回值可以是父类返回值的子类(gcc中),参数不可以

     

    将析构函数写为virtual 防止通过父类指针释放时 没有调用子类析构函数

        但构造函数不能是虚拟的  

        析构函数可以是inline的

     

    纯虚函数 virtual void f()=0;

    含有纯虚函数的类称为抽象类,不能实例化,子类若未实现纯虚函数也不能实例化

    阻止类的实例化 还可以用private构造函数

     

    多继承中,如果几个父类又共同继承自一个类(菱形继承),应使用虚继承

    class A;

      class B:public virtual A;

      class C:public virtual A;

    class D:public B,public C;

     

    5.  模板

    template<class Type, int size> 在模板参数表中typenameclass等价,size在模板实例化时替换为一个常量  

    模板在继承时也要带上Type   :public A<Type>

     

    成员函数定义

    Template<class T>

    Void A<T>::f(){}

     

    类模板的成员函数定义也要写在头文件中,因为模板函数在调用时才编译

    export关键字编译器不支持,或者include cpp文件)

     

    模板类继承  class Extend_queue:public Queue<Entry>

     

    6.  STL

    vector,list(双向链表),deque,stack,

    queue,priority_queue(后三种是容器适配器,没有迭代器)

    map(关联容器,红黑树实现),set(集合,不重复,红黑树实现),multiset(允许重复)

    algorithm头文件 for_each为每个元素调用指定函数  stable_sort稳定排序

     

    vector

        vector<int> vec;

        vec.push_back(12);

        vector<int>::iterator p;

        p = vec.begin();

        *p = 68;

        cout<<vec[0]<<endl;

    删除vector时会将存储的对象也析构 ,所以如果对象没有拷贝构造,可能会两次释放同一内存

    Push_back对象的时候会调用两次拷贝构造,一次析构


    最新回复(0)