• 2012国庆回来复习 笔记整理


    内存分配有三种方式


    1 静态分配,或者说静态存储区域分配。

    就是说内存在程序编译的时候就已经分配好了,这款内存在程序整个运行期间都存在,如全局变量,static变量。

    2 自动分配,或者说是在栈上分配。

    比如在执行函数时,函数内局部变量的存储单元就是在栈上创建的,函数执行结束时,这些存储单元自动被释放。

    3 堆上分配,或者说是动态内存分配。

    那些用malloc和new申请来的内存,就是动态的,在堆上分配的。这些堆上分配出来的空间,由申请使用他们的那些人负责释放。

        补充:堆开辟内存空间时,是向着内存空间增加的方向的。而栈则是向下的,就是向着内存地址减少的方向。

    重载,覆盖,隐藏

    覆盖就是派生类函数覆盖基类的函数。满足覆盖的条件:派生类和基类的函数名相同,参数也相同,基类的函数必须有virtual。

    隐藏是指派生类的函数屏蔽了与其同名的基类函数。满足隐藏的条件:派生类和基类的函数名相同,参数不同,不管有无virtual,都算隐藏。或者,派生类和基类函数名相同,参数相同,没有virtual,也算隐藏(有了virtual算什么,往上看)

    重载就是有几个函数名相同,但是参数不同的函数。重载发生在相同范围,一定是同一个类。

     运算符重载 virtual关键字可有可无 operator不影响优先级

    不是所有的运算符都能被重载,以下运算符就不行:

    :: 作用域解析运算符

    ?: 条件运算符

    . 直接成员运算符

    .* 接解除类成员指针引用运算符

    sizeof 

    动态绑定 早期绑定

    通过静态解析的基类指针来调用函数,都会调用基类函数。函数通过指针的静态,仅取决于指针的类型,而不取决与对象。

    对于一个基类指针或者引用,定义时的类型称为静态类型,实际指向对象的类型称为动态类型。

    在任意时候指针pbox都可以指向包含以box为其基类的 派生类的地址,这里的pbox 声明为box* 类型。

    多态是通过基类指针、基类引用调用函数实现多态特性。

    我们用virtual关键字来避开静态绑定。

    动态绑定的条件,被调用函数必须是虚函数,必须通过基指针或者基类引用来调用。如果通过this指针间接调用虚函数也是动态调用。

    动态调用必须是针对虚函数的调用,不能是针对一般成员函数的调用,并且就算把成员函数声明为虚函数,还要用基类指针或者基类引用直接调用,或者通过this指针间接调用这两个条件才能实现动态调用。

    对于一般成员函数(非虚函数)必定是静态调用。

    如果基类中把一个函数定义成虚函数,那么所有派生类中都有相同的返回值类型,函数签名,包括const也被认为是虚函数。反之,如果在派生类中,函数的返回值,签名,只有有一个和基类不同,在调用的时候就不会认为是基类的虚函数,此时执行静态调用。

    如果虚函数在基类声明中带有默认参数值,那么在动态调用中,总是使用基类声明中的默认值。

    有几个情况是静态调用函数:

    设pbox是基类的指针,rbox是基类引用形参,volume()是虚函数。

    使用类名和作用域运算符来强调调用指定类的虚函数,如:

    pbox->Box::volume()

    rbox.Box::volume()

    使用对象名和成员运算符来调用虚函数是总是静态调用的

    hardcase.volume(); 显式调用运算的hardcase的volume()

    另外,用基类指针来调用一般成员函数(非虚函数)总是静态调用

    基类指针和派生类指针 之间的 转换

    派生类指针可以直接转化为基类指针

    但是倒过来,基类指针不能隐式地转换成派生类指针,如果一定要,那么就是用强制类型转换,并且这种方式不保证一定成功。

     关于派生类和基类直接的转换代码

    #include<iostream>
    using namespace std;
    
    class box
    {
          public:
           virtual    void yoyo()
                 {
                      cout<<"Box yoyo"<<endl;
                  }
    };
    
    class carton:public box
    {
          public:
                 void yoyo()
                 {
                      cout<<"carton yoyo"<<endl;
                 }
    };
    
    class cerealpack:public carton
    {
          public:
                 void yoyo()
                 {
                      cout<<"cerealpack yoyo"<<endl;
                 }
    };
    
    int main()
    {
        carton ca;
        carton *pca = &ca;
    
        cerealpack ce;
        cerealpack *pce = &ce;
    
        box bo;
        box* pbo = &bo;
    
        pce->yoyo();
        pce = static_cast<cerealpack*>(pbo);
        pce->yoyo();
    
    return 0; }
  • 相关阅读:
    AJAX
    前端上传文件 后端PHP获取文件
    PHP基础语法
    JS错误记录
    JS学习笔记
    python利用xlrd读取excel文件始终报错原因
    安装xlwt和xlrd
    编程菜鸟的日记-Linux无处不在
    编程菜鸟的日记-《软件测试》Ron Patton著-读书笔记
    编程菜鸟的日记-初学尝试编程-C++ Primer Plus 第6章编程练习9
  • 原文地址:https://www.cnblogs.com/ligongzi/p/2716751.html
Copyright © 2020-2023  润新知