zoukankan      html  css  js  c++  java
  • 深入探索C++对象模型(Inside the C++ object model) -- 摘阅笔记(关于对象

    Object Lessons 关于对象

    在C语言中,“数据”和“处理数据的操作(函数)”是分开声明的,也就是说 ,语言本身并没有支持“数据和函数”之间的关联性。把这种程序方法称为程序性(procedural),由一组“分布在各个以功能为导向的函数中”的算法所驱动,它们处理的是共同的外部数据。

     1 typedef struct point3d
     2 {
     3   float x;
     4   float y;
     5   float z;
     6   
     7 }Point3d;
     8 
     9 //打印一个Point3d,就需要定义一个这样的函数
    10 void Point3d_print(const Point3d *pd)
    11 {
    12   printf("(%g, %g, %g)", pd->x, pd->y, pd->z);
    13 }
    14 //为了效率高点,可以定义成宏
    15 #define Point3d_print( pd ) 
    16     printf("(%g, %g, %g)", pd->x, pd->y, pd->z);
    17 
    18 //更直接的是直接在一个程序中完成操作
    19 void my_foo()
    20 {
    21   Point3d *pd = get_a_point();
    22   ....
    23   /* 直接打印出 point .... */
    24   printf("(%g, %g, %g)", pd->x, pd->y, pd->z);
    25 }
    26 
    27 //对于某个点的坐标可以直接存取
    28 Point3d pt;
    29 pt.x = 0.0;
    30 // 或者直接定一个处理宏
    31 #define X(p, xval) (p.x) = (xval)
    32 ...
    33 X(pt, 0.0);

    在C++中, Point3d采用“抽象数据类型(abstract data type, ADT)”来实现:

     1 class Point3d 
     2 {
     3   friend ostream& operator<<(ostream &os, const Point3d &pt);
     4 public:
     5     Point3d(float x = 0.0, float y = 0.0, float z = 0.0)
     6     :_x(x), _y(y), _z(z){}
     7   
     8   float x() const { return _x; }
     9   float y() const { return _y; }
    10   float z() const { return _z; }
    11   
    12   void x(float xval ) { _x = xval; }
    13   void y(float yval ) { _y = yval; }
    14   void z(float zval ) { _z = zval; }
    15   
    16 private:
    17   float _x;
    18   float _y;
    19   float _z;
    20 };
    21 inline ostream& operator<<(ostream &os, const Point3d &pt)
    22 {
    23     os << "(" << pt.x() << "," << pt.y() << "," << pt.z() << ")";
    24 };

    或者一个双层或者三层clasa层结构完成

     1 class Point {
     2 public:
     3   Point(float x = 0.0): _x(x) {}
     4   
     5   float x() const { return _x; }
     6   
     7   void x(float xval) { _x = xval; }
     8 protected;
     9   float _x;
    10 };
    11 
    12 class Point2d : public Point 
    13 {
    14 public: 
    15   Point2d(float x = 0.0, float y = 0.0)
    16     :Point(x), _y(y) {}
    17   
    18   float y() { return _y; }
    19   
    20   void y(float yval) { _y = yval; }
    21 protected:
    22   float _y;
    23 };
    24 
    25 class Point3d: public Point2d
    26 {
    27 public:
    28   Point3d(float x = 0.0, float y = 0.0, float z = 0.0)
    29       : Point2d(x, y), _z(z) {}
    30   
    31   float z() { return _z; }
    32   
    33   void z( float zval) { _z = zval; }
    34 protected:
    35   float _z;
    36 }
    37 
    38 template< class T>
    39 class Point3d
    40 {
    41 public:
    42   Point3d(T x = 0.0, T y = 0.0, T z = 0.0)
    43     : _x(x), _y(y),_z(z) {}
    44   
    45  T x() const { return _x; }
    46  T y() const { return _y; }
    47  T z() const { return _z; }
    48  
    49  void x(T xval ) { _x = xval; }
    50  void y(T yval ) { _y = yval; }
    51  void z(T zval ) { _z = zval; }
    52  
    53 private:
    54   T _x, _y, _z;
    55 };
    56 
    57 template<class T, int dim>
    58 class Point
    59 {
    60 public:
    61   Point();
    62   Point(T coords[dim]) {
    63     for (int index = 0; index < dim; index++)
    64       _coords[index] = coords[index];
    65   }
    66   
    67   T& operator[] (int index){
    68     assert(index < dim && index >= 0);
    69     return _coords[index]; 
    70   }
    71   
    72   T operator[] (index) const {
    73     assert(index < dim && index >= 0);
    74     return _coords[index];
    75   }
    76   
    77   // ... etc
    78 private:
    79   T _coords[dim];
    80 };
    81 
    82 inline
    83 template <class T, int dim>
    84 ostream & operator<<(ostream &os, const Point<T, dim> &pt)
    85 {
    86   os << "(";
    87   for (int ix = 0; ix < dim - 1; ix++)
    88     os << pt[ix] << ", ";
    89   os << pt[dim - 1];
    90   os << ")";
    91 }

    从软件工程的眼光来看,为什么“一个ADT或class hierarchy的数据封装”比“在C程序中程序性地使用全局数据”好。

    加上封装后的布局成本(layout costs for adding Encapsulation)

    增加封装后,布局成本增加了多少?答案是 class Point3d并没有增加多少成本。三个data membeers 直接内含在一个class objects之中,就像C struct 的情况一样。而member function虽然含在class的声明之内,却不出现在object之中。 每一个non-inline member function只会诞生一个函数实例。至于每一个“拥有零个或一个定义的”的inline function 则会在其每一个使用者(模块)身上产生一个函数实例。

    C++在布局以及存取时间上主要的额外负担是由virtual引起的, 包括;

    • Virtual function 机制,用以支持一个有效的“执行期绑定”(runtime binding)

    • Virtual base class 用以实现“多次出现在继承体系中的base class, 有一个单一而被共享的实例“

    • 多重继承下的额外负担, 发生在“一个derived class 和其第二或后继之后base class 的转换”之间。

    一般,没有什么天生的理由说C++程序一定比其C程序庞大或迟缓。

     

  • 相关阅读:
    洛谷P2664 树上游戏(点分治)
    洛谷P3366 【模板】最小生成树(Boruvka算法)
    loj#2312. 「HAOI2017」八纵八横(线性基 线段树分治)
    noi.ac#309 Mas的童年(子集乱搞)
    loj#6041. 「雅礼集训 2017 Day7」事情的相似度(SAM set启发式合并 二维数点)
    Windows phone应用开发[22]-再谈下拉刷新
    Windows phone应用开发[21]-图片性能优化
    Windows phone应用开发[20]-禁止Pivot手势
    Windows phone应用开发[19]-RSA数据加密
    Windows phone应用开发[18]-下拉刷新
  • 原文地址:https://www.cnblogs.com/Davirain/p/13375702.html
Copyright © 2011-2022 走看看