最新公告
  • 欢迎您光临波比源码,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入我们
  • 重温《Inside The C++ Object Model》(1) –关于对象

    C/C++ 编程风格

    //1.C风格(结构化程序设计):数据和函数(操作)没有任何关联性
    typedef struct Point3d
    {
    float x;
    float y;
    float z;
    } Point3d_t;

    void
    Point3d_print(const Point3d_t *pd)
    {
    printf("%g, %g, %g
    ", pd->x, pd->y, pd->z);
    }

    //2.基于对象(Object-Base):提供抽象数据类型(ADT)来支持封装
    class Point3d
    {
    friend ostream &operator<<(ostream &os, const Point3d &pt);
    public:
    Point3d(float x = 0.0, float y = 0.0, float z = 0.0):
    _x(x), _y(y), _z(z) {}

    float x()
    {
    return _x;
    }
    float y()
    {
    return _y;
    }
    float z()
    {
    return _z;
    }

    void x(float xval)
    {
    _x = xval;
    }

    //etc…

    private:
    float _x;
    float _y;
    float _z;
    };

    inline ostream &
    operator<<(ostream &os, const Point3d &pt)
    {
    return os << "( " << pt._x << ", " << pt._y << ", "
    << pt._z << " )";
    }

    //3.面向对象(Object-Oriented-Model):提供继承和多态
    class Point
    {
    public:
    Point(float x = 0.0):
    _x(x) {}

    float x()
    {
    return _x;
    }

    void x(float xValue)
    {
    _x = xValue;
    }

    protected:
    float _x;
    };

    class Point2d : public Point
    {
    public:
    Point2d(float x = 0.0, float y = 0.0):
    Point(x), _y(y) {}

    float y()
    {
    return _y;
    }
    void y(float yValue)
    {
    _y = yValue;
    }

    protected:
    float _y;
    };

    class Point3d : public Point2d
    {
    friend inline ostream &
    operator<<(ostream &os, const Point3d &pt);

    public:
    Point3d(float x = 0.0, float y = 0.0, float z = 0.0):
    Point2d(x, y), _z(z) {}

    float z()
    {
    return _z;
    }
    void z(float zValue)
    {
    _z = zValue;
    }

    private:
    float _z;
    };

    inline ostream &
    operator<<(ostream &os, const Point3d &pt)
    {
    return os << "( " << pt._x << ", " << pt._y << ", "
    << pt._z << " )";
    }

    //4.面向泛型:提供模板提供类型无关化的编程风格
    //示例(1):仅提供类型参数化
    template <typename Type>
    class Point3d
    {
    public:
    Point3d(Type x = 0.0, Type y = 0.0, Type z = 0.0):
    _x(x), _y(y), _z(z) {}

    Type x()
    {
    return _x;
    }
    Type y()
    {
    return _y;
    }
    Type z()
    {
    return _z;
    }

    void x(const Type &xval)
    {
    _x = xval;
    }

    //etc…

    private:
    Type _x;
    Type _y;
    Type _z;
    };

    //示例(2):同时提供类型和数目(int dim)参数化
    template <typename Type, int dim>
    class Point
    {
    public:
    Point() {}
    Point(Type coordes[dim])
    {
    for (int index = 0; index < dim; ++index)
    {
    _coordes[index] = coordes[index];
    }
    }

    const Type &operator[](int index) const
    {
    assert(index < dim && index >= 0);
    return _coordes[index];
    }

    private:
    Type _coordes[dim];
    };

    template <typename Type, int dim>
    inline ostream &operator<<(ostream &os, const Point< Type, dim > &pt)
    {
    os << "( ";
    for (int i = 0; i < dim; ++i)
    os << pt[i] << ", ";
    os << ")";
    return os;
    }

    //测试
    int array[] = {11,12,333};
    Point<int, 3> point(array);
    cout << point << endl;
    cout << point[2] << endl;

    小结:C++加上封装的布局本钱

    (1)3个data-member[数据成员]直接内含在每个class-object[对象]当中,犹如C-Struct1样;

    (2)Member-function虽然存在于class的声明中, 却不出现在object当中, 每个non-inline member function[非inline的成员函数]只会诞生1个函数实体;

    (3)而inline member function会在其每个使用者身上产生1个函数实体.

     

    C++对象模型

    1.所有的数据成员(static 数据成员除外)寄存在每个对象当中;

    2.[1]static 数据成员,[2]成员函数(不管是static/non-static)寄存在所有对象以外;

    3.对virtual-functions, 每个对象都有1个vptr(指向1个vtbl(包括type_info object, virtual functions)).

    因此:内存中对象的大小

    (1)其non-static data member 的总和大小

    (2)加上任何alignment(内存对其)的需求而弥补上去的空间[可能存在于members中间, 也可能存在于集合体边界];

    (3)加上支持virtual[vptr]而由内部产生的任何额外负担.

    //测试
    class Point1
    {
    };

    class Point2
    {
    private:
    int number;
    };

    class Point3
    {
    public:
    Point3(int _number = 0): number(_number) {}
    ~Point3() {}
    static void showCount()
    {
    std::cout << "Point3_count = " << Point3_count << std::endl;
    }

    private:
    static int Point3_count;

    private:
    int number;
    };

    class Point4
    {
    public:
    virtual ~Point4();

    private:
    int number;
    };

    int main()
    {
    cout << sizeof(Point1) << endl;
    cout << sizeof(Point2) << endl;
    cout << sizeof(Point3) << endl;
    cout << sizeof(Point4) << endl;
    }

    对象在内存中的布局

    Derived Class 的Object 和 Pointer布局(以下图)


    (其实ZooAnimal subobject 的布局有些毛病, string类型在现代C++中只占4个字节, 因此ZooAnimal subobject所占的内存空间唯一12字节, 而不是图中的16字节)

    说明:

    (1)pointer & reference 都只需1个字长(x86_32中为4个字节)的空间;

    (2)派生类对象中:基类子对象与派生类子对象在内存中的位置是相邻的.

    //测试
    class ZooAnimal
    {
    public:
    ZooAnimal() {}
    virtual ~ZooAnimal() {}
    virtual void rotate() {}

    protected:
    int loc;
    string name;
    };

    class Bear : public ZooAnimal
    {
    public:
    Bear() {}
    ~Bear() {}

    void rotate()
    {

    }

    protected:
    enum Dances
    {
    //…
    };
    Dances dances_known;
    int cell_block;
    };

    int main()
    {
    Bear b;
    ZooAnimal *pz = &b;
    Bear *pb = &b;

    cout << "Pointer…" << endl;
    cout << sizeof(pz) << endl;
    cout << sizeof(pb) << endl;

    cout << "
    Object…" << endl;
    cout << sizeof(*pz) << endl;
    cout << sizeof(*pb) << endl;

    cout << "
    Class…" << endl;
    cout << sizeof(ZooAnimal) << endl;
    cout << sizeof(Bear) << endl;
    }

    测试说明:

    pb 所涵盖的地址包括了全部Bear Object, 而 pz只包括了Bear Object中的ZooAnimal SubObject!

    波比源码 – 精品源码模版分享 | www.bobi11.com
    1. 本站所有资源来源于用户上传和网络,如有侵权请邮件联系站长!
    2. 分享目的仅供大家学习和交流,您必须在下载后24小时内删除!
    3. 不得使用于非法商业用途,不得违反国家法律。否则后果自负!
    4. 本站提供的源码、模板、插件等等其他资源,都不包含技术服务请大家谅解!
    5. 如有链接无法下载、失效或广告,请联系管理员处理!
    6. 本站资源售价只是赞助,收取费用仅维持本站的日常运营所需!
    7. 如遇到加密压缩包,请使用WINRAR解压,如遇到无法解压的请联系管理员!

    波比源码 » 重温《Inside The C++ Object Model》(1) –关于对象

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    波比源码
    一个高级程序员模板开发平台
    升级波友尊享更多特权立即升级