美文网首页
C++面向对象编程(下)第二周笔记 GeekBand

C++面向对象编程(下)第二周笔记 GeekBand

作者: CharlesW | 来源:发表于2016-06-13 09:09 被阅读0次

    1.对象模型

    C++对象模型中,non static数据成员被放置到对象内部,static数据成员,static and non static函数成员均被放到对象之外。
    而对于虚函数的支持则分两步完成:
    1.每一个class产生一堆指向虚函数的指针,放在表格之中。这个表格称之为虚函数表(virtual table,vtbl)。
    2.每一个对象被添加了一个指针,指向相关的虚函数表vtbl。通常这个指针被称为vptr。vptr的设定(setting)和重置(resetting)都由每一个class的构造函数析构函数拷贝赋值运算符自动完成。

    图 1 对象模型

    例如图1中,由于A类中有虚函数,所以A类的对象中有自己的两个成员变量m_data1、m_date2和一个指向vtbl的指针(vptr)。B类是A类的子类,B类对象除了有父类对象所有成员和vptr外,还有自己的成员m_data3。这些对象占用内存的大小由它们的成员变量和vptr指针决定,在不同的编译环境下它们的内存大小会有所不同。

    2.const

    当类中成员函数的const和non-const版本同时存在时,const对象只会调用const版本,non-const对象只会调用non-const版本。
    const对象和non-const对象都可以调用const成员函数;
    non-const对象可以调用non-const成员函数而const对象则不可以。
    例如以下程序:

    #include <iostream>
    
    class Foo
    {
        public:
            Foo(int id) : id_(id) { }
            void print() const {
                std::cout<<"const print id:"<<id_<<std::endl;
            }
            void print() {
                std::cout<<"non-const print id:"<<id_<<std::endl;
            }
            void say() {
                std::cout<<"say id:"<<id_<<std::endl;
            }
            void tell() const {
                std::cout<<"tell id:"<<id_<<std::endl;
            }
        private:
            int id_;
    };
    
    int main()
    {
        Foo a1 = Foo(6);
        const Foo a2 = Foo(5);
        a1.print();
        a2.print();
        a1.say();
        a1.tell();
        //a2.say();  //[Error] passing 'const Foo' as 'this' argument of 'void Foo::say()' discards qualifiers [-fpermissive]
        return 0;
    }
    
    图 2 测试结果

    例中print函数同时有const和non-const版本,const对象和non-const对象都能调用对应的版本。而const对象调用non-const成员函数时编译会出错。

    3.重载new和delete

    C++中new,delete,new[],delete[]是可以重载的,这样可以在程序执行new或delete时另外地实现我们自己所想要的操作。
    new,delete,new[],delete[]的重载分为全局重载和对特定类的重载。
    例如:
    全局重载

    //global operator new/delete
    void* myAlloc(size_t size){
        return malloc(size);
    }
    
    void myFree(void* ptr){
        return free(ptr);
    }
    
    inline void* operator new(size_t size){
        std::cout<<"global new() \n";
        return myAlloc(size);
    }
    
    inline void operator delete(void* ptr){
        std::cout<<"global delete() \n";
        return myFree(ptr);
    }
    

    对A类对象new,delete的重载

    class A {
    
        int id;
    public:
        A(int i):id(i){
            std::cout<<"A构造 \n";
        }
        ~A(){
            std::cout<<"A析构 \n";
        }   
        static void* operator new(size_t size);
        static void operator delete(void* pdead,size_t size);
    };
    
    //member operator new/delete
    void* A::operator new(size_t size) {
        A* p = (A*)malloc(size);
        std::cout<<...........;
        return p;
    }
    
    void A::operator delete(void* pdead,size_t size) {
        std::cout<<...........;
        free(pdead);
    }
    

    相关文章

      网友评论

          本文标题:C++面向对象编程(下)第二周笔记 GeekBand

          本文链接:https://www.haomeiwen.com/subject/gxkydttx.html