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

1.对象模型

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

C++面向对象编程(下)第二周笔记 GeekBand_第1张图片
图 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 

class Foo
{
    public:
        Foo(int id) : id_(id) { }
        void print() const {
            std::cout<<"const print id:"<
C++面向对象编程(下)第二周笔记 GeekBand_第2张图片
图 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)