zoukankan      html  css  js  c++  java
  • 《深度探索C++对象模型》——C++与C程序风格对比

    C语言中,“数据”和“处理数据的操作(函数)”是分开来声明的。由一组“分布在各个以功能为导向的函数中”的算法所驱动,处理共同的外部数据。

    先看一个例子:

    如果我们声明一个struct Point3d

    typedef struct point3d
    {
    	float x;
    	float y;
    	float z;
    }Point3d;
    

    欲打印一个Point3d,可能就得定义一个像这样的函数:

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

    或者,定义这样的宏:

    #define Point3d_print( pd ) 
    	printf("(%g, %g, %g)
    ", pd.x, pd.y, pd.z);
    

    或者,直接在程序调用处完成其操作:

    void 
    my_foo()
    {
    	Point3d *pd = get_a_point();
    	...
    	/*直接打印出  point ...*/
    	printf("(%g, %g, %g)
    ", pd.x, pd.y, pd.z);
    }
    

    同样的道理,某个点的特定坐标值可以直接存取:

    Poind3d  pt;
    pt.x = 0.0;
    

    或者,

    #define X( p, xval ) (p.x) = (xval);
    …
    X( pt, 0.0);
    

    在C++中,Point3d有可能用独立的“抽象数据类型(ADT)”来实现:

    class Point3d
    {
    public:
    	Point3d( float x = 0.0, float y = 0.0, float z = 0.0 ):
    	  _x(x), _y(y), _z(z){}
    	~Point3d(){}
    	float x(){ return _x;}
    	float y(){ return _y;}
    	float z(){ return _z;}
    	//...etc..
    private:
    	float _x;
    	float _y;
    	float _z;
    };
    
    inline ostream&
    	operator<<(ostream &os, const Point3d &pt)
    {
    	os << "(" << pt.x << "," << pt.y << "," << pt.z << ")";
    };
    

    或者,

    class Point {
    public:
    	Point( float x = 0.0 ):_x(x){}
    	float x(){return _x;}
    	void x( float xval ){ _x = xval;}
    	//...
    protected:
    	float _x;
    };
    
    class Point2d : Point {
    public:
    	Point2d( float x = 0.0, float y = 0.0 ):Point(x), _y(y){}
    	float y(){ return _y; }
    	void y( float yval ){ _y = yval; }
    	//...
    protected:
    	float _y;
    };
    
    class Point3d : Point2d {
    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 zval ){ _z = zval;}
    	//...
    protected:
    	float _z;
    };
    

    或者,坐标类型参数化:

    template < class type >
    class Point3d
    {
    public:
    	Point3d( type x = 0.0, type y = 0.0, type z = 0.0 ):
    	  _x(x), _y(y), _z(z){}
    	~Point3d(){}
    	type x(){ return _x;}
    	type y(){ return _y;}
    	type z(){ return _z;}
    	void x( type xval ){ _x = xval;}
    	//...etc..
    private:
    	type _x;
    	type _y;
    	type _z;
    };
    

    或者,坐标类型和坐标数目均参数化:

    template< class type, int dim>
    class Point
    {
    	~Point(){};
    	Point( type coords[dim] ){
    		for( int index = 0; index < dim; index++ )
    			__coords[index] = coords[index];
    	}
    	type& operator[]( int index ){
    		assert(index < dim && index >= 0);
    		return __coords[index];
    	}
    	//...etc...
    private:
    	type __coords[dim];
    };
    
    inline 
    	template< class type, int dim>
    ostream&
    	operator<<( ostream &os, const Point< type, dim> &pt )
    {
    	os << "(";
    	for ( int ix = 0; ix < dim - 1; ix++)
    	{
    		os << pt[ix] << ", ";
    	}
    	os << pt[dim - 1];
    	os << ")";
    };
    

    根据上面的例子,很明显的看出,C 程序和 C++ 程序风格上有截然不同,在程序的思考上也有明显的差异。大家看到 Point3d 转到 C++ 之后,是不是反而更加复杂?布局成本是不是增加更多了?答案是 class Point3d 并没有增加成本。三个 data member 直接内含在每一个 class object 之中,就像 C struct  的情况一样。而 member function 虽然含在 class 的声明之内,却不出现在 object 之中。每一个 non-line member function 只会诞生一个函数实体,而不是 inline function 在每一个模块使用者身上产生一个函数实体。事实上,C++ 在布局以及存取时间上主要的额外负担是由 virtual 引起的,包括:

    • virtual function 机制  用以支持一个有效率的“执行期绑定”(running binding
    • virtual base class     用以实现“多次出现在继承体系中的base class ,有一个单一而被共享的实体”。

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

    至此,你也许会问,你咋知道 C++ 的布局成本没有增加成本?C++ 布局又是咋样的?这里面说的 virtual又是怎么给 C++ 在布局以及存取时间上引起额外的负担?敬请关注下一篇博客《C++对象模型》。

     

  • 相关阅读:
    求s=a+aa+aaa+aaaa+aa...a的值,其中a是一个数字。
    getchar函数
    计算机网络04-ip与子网划分
    计算机网络03-传输层、可靠数据传输、UDP与TCP
    计算机网络02-应用层(http、email、dns)
    游戏-图形学学习路线
    markDown 入门
    webpack 入门级 傻瓜式教学
    npm 切换 cnpm 切换淘宝镜像源
    vue 父组件在接收子组件的同时传递一个当前的数据
  • 原文地址:https://www.cnblogs.com/iyoyos/p/4222842.html
Copyright © 2011-2022 走看看