zoukankan      html  css  js  c++  java
  • 菱形继承-虚继承-静态成员-new、delete的误区

    菱形继承

    • 最底下子类从基类继承的成员变量冗余,重复
    • 最底下子类无法访问基类的成员,有二义性

    虚继承

    • 虚继承可以解决菱形继承带来的问题
    • 两个虚继承共用一个m_age
    • Person类被称为虚基类
    struct Person { int m_age;};
    struct Student : virtual Person { ...};
    struct Worker : virtual Person { ...};
    struct Undergraduate : Student, Worker { ...};
    
    • 虚表指针与本类起始的偏移量(一般是0)
    • 虚基类第一个成员变量与本类起始的偏移量

    注意上面两句话,这不是学习的环境,因为你只能看见以上两句话,看不懂可以直接放弃理解。学习环境为视频加比喻加图片,生动形象。

    • 真实的学习环境理解方式为:仓库拿东西时,你一进门有人告诉你,前面第8个房间(偏移量8)
    • 啥时候不能放弃?发现新东西时。在知识面逐渐充足时,明明万事俱备只欠东风时,就需要坚持下去。

    静态成员(static)

    • 静态成员:被static修饰的成员变量函数
    • 存储在数据段(全局区,类似于全局变量),整个程序运行过程中只有一份内存
    • 对比全局变量,可以设定访问权限(public、protected、private),达到局部共享的目的
    • 必须在类外面初始化,不能使用static
    • 内部不能使用this指针,没有对象传地址给this()
    class Car {
    public:
        static int m_price;
        void run() {
            cout << "run()" << endl;
        }
    };
    
    // 初始化成员变量
    int Car::m_price = 0;
    
    int main() {
        Car car1;
        car1.m_price = 100;
    
        Car car2;
        car2.m_price = 200;
    
        Car::m_price = 300;
        
        Car *p = new Car();
        p->m_price = 400;
        delete p;    //对象销毁与数据段中的静态变量没有关系
        
        getchar();
        return 0;
    }
    

    静态成员与全局变量是同一个东西,汇编层

    class Car{
    public:
        int m_age;
    };
    ...
    Car car1;
    car1.m_age = 1;
    ...
    dword ptr [ebp-8],1    //ebp-8,栈空间
    
    class Car{
    public:
    static int m_price
    };
    // 在类外面初始化成员变量
    int Car::m_price = 2;
    dword ptr ds:[00A9A314h],2    //ds,data segment 数据段(全局区)
    
    int g_age; int main() { g_age = 0;}
    dword ptr ds:[00A9A318h],0    //与静态成员变量一样
    
    class Car {};
    
    Car g_car;    //全局区创建对象
    
    int main() {
        Car car;    //栈空间创建对象
        Car *p = new Car();    //堆空间创建对象
    };
    

    单例模式

    • 设计模式的一种,保证某个类永远只创建一个对象
      1.构造函数私有化
      2.定义一个私有的static成员变量指向唯一的那个单例对象
      3.提供一个公共的访问单例对象的接口
    
    class Rocket {
    private:
        Rocket() {}    //构造函数私有化
        static Rocket *ms_rocket;    //定义一个私有的static成员变量指向唯一的那个单例对象
    public:
        static Rocket *sharedRocket() {    //提供一个公共的访问单例对象的接口
            if (ms_rocket == NUll) {
                ms_rocket == new Rocket();
            }
            return ms_rocket;
        }
        static void deleteRocket() {
            if (ms_rocket != NULL) {
                delete ms_rocket;    //只是回收指针的指向
                ms_rocket = NULL;    
            }
        }
    };
    Rocket *Rocket::ms_rocket = NULL;
    
    int main() {
        Rocket *p = Rocket::sharedRocket();
    }
    

    new、delete的误区

    int *p = new int;
    *p = 10;
    delete p;    // 回收堆空间(4个字节),这块空间可以被重新使用
    
  • 相关阅读:
    第10组 Beta冲刺(4/4)
    第10组 Beta冲刺(3/4)
    第10组 Beta冲刺(2/4)
    第10组 Beta冲刺(1/4)
    第10组 Alpha冲刺(4/4)
    租房这件事
    idea中的maven工程,有的项目名称显示粗体,有的显示中括号
    win10电脑版微信数字输入的间隔变大解决办法
    在实体类中添加了@ApiModel不起作用
    为数字字符串加上千分位符号
  • 原文地址:https://www.cnblogs.com/sec875/p/12317570.html
Copyright © 2011-2022 走看看