• C++面向对象高级编程(下)第二周-Geekband


    17,对象模型:关于vptr(vitrual Pointer)和vtbl(virtual Table)

    当存在虚函数就会出现虚指针vptr指向虚函数所在位置vtbl

    将vptr实现vtbl内容翻译为C:
    (*p->vptr)n;
    (* p->vptr[n])(p);

    动态绑定: 虚机制
    1,指针
    2,向上转型保证安全
    3,调用的是虚函数

    18, this指针

    [Template Method]

    This->Serialize()实现:
    (*(this->vptr)[n])(this) -动态绑定

    这里的n依旧没有得到解释.

    19, 动态绑定

    向上转型 : 指针实现

    如 B继承A
    B b;
    A a = (A)b;
    a.vfunc1(); 此时,是静态绑定!! 调用的是A类的vfunc1()

    A* pa = new B;
    pa->vfunc1(); 这里必须是动态绑定啊!这里是指针.

    pa = &b;
    pa->vfunc1(); 这里依旧是动态绑定.

    20,const

    void function() const { return data;}
    const一般放在成员函数后头,不放在全局函数后头.
    在成员函数后面加const是属于签名, 就是当两个成员函数传参相同,那么加不加const也会被区分成两个函数.
    那这里如何区分调用情况呢?

    在内存共享的情况下, 要考虑内容被更改时所产生的问题.
    class template::std::basic_string<..>有如下成员函数:
    charT operator[] (int n) const
    { //不必考虑COW}
    reference operator[] (int n)
    { //必须考虑COW }

    COW: Copy on write

    所以这个类里面, 当定义的是常量对象的时候,就会被强制调用const成员函数, 当定义的不是常量对象,那么就会调用非const成员函数.

    const和non-const
    那么这里,当是非常量对象时, 也可以const成员函数呀!
    规则:
    当成员函数的const和non-const版本都存在<>时, const对象只能调用const版本, non-const对象只能调用non-const版本.

    21, 关于New , Delete

    new对象的流程不能更改,但是实现过程中的函数可以被更改.
    operator new
    operator delete

    22, 重载::operator new, ::operator new[],::operator delete ,::operator delete[]

    在全局当中:
    注意: 如果你重载了全局的操作符, 所以要额外小心.
    这些重载不可以被声明在一个namespace中.

    //这里的函数是编译器去调用, 所以size是编译器给出.
    void* operator new( size_t size )
    { return malloc(size);}

    void* operator new[]( size_t size )
    { return malloc(size);}

    void* operator delete(void* ptr )
    { free(ptr);}

    void* operator delete[](void* ptr )
    { free(ptr);}

    重载 member new , delete

    在class里面重载new, delete

    class foo{
    public:
    void* operator new(size_t size);
    void operator delete(void *, size_t size); //size为可选
    …….

    };
    那么你在:
    foo *a = new foo;
    delete a;
    就会调用上面重载的函数.

    new[] , delete[] 也如此.

    23, 实例

    当类中重载了new , delete , 而又想调用全局的new , delete
    可以这样写:
    ::delete a;

    string类内其实是一个指针.

    当创建一个数组的时候, 内存当中就会多分配一个指针,该指针用于保存当前数组个数.

    24, 重载 new(), delete() 示例

    允许重载成员函数new(….) 其中参数中,必须有第一个且第一个必须是size_t size. 其余参数以new所指定的placement argument为初值.

    Foo* p = new(300,’c’)Foo; //这里是三个参数

    我们也可以重载类成员函数 operator delete() ,写出多个版本. 但他们绝不会被 通常所使用的delete调用.只有当new所调用的ctor抛出 异常,才会调用这些重载版的operator delete(). 它们只能这样被调用,主要用来归还未能完全创建成功的对象所占用的内存.

    25, Basic_String使用new(extra)扩充申请量

    Basic_String在重载new()过后,传递了一个extra参数, 用于后台自动多申请extra空间。

  • 相关阅读:
    带你正确的使用List的retainAll方法求交集
    Java URL
    如何正确的创建线程
    小贾漫谈——Java反射
    二、定时器的应用
    网络获取json数据并解析
    异步消息处理机制Handler
    手机安全卫士——Splash总结
    click事件触发也有失灵的时候?
    一张图看透微信公众号、企业号、小程序
  • 原文地址:https://www.cnblogs.com/skyhuangdan/p/5486764.html
Copyright © 2020-2023  润新知