zoukankan      html  css  js  c++  java
  • Nonstatic Member Function 的语意

    C++ 的设计准则之一就是: nonstatic member function 至少必须和一般的 nonmember function 有相同的效率。 这就是说, 如果我们在以下两个函数之间做选择:

    float magnitude3d(const Point3d *_this){...}
    float Point3d::magnitude3d() const {...}

    那么选择 member function 不因该有什么额外负担, 这是因为编译器内部已将 member 函数实体转换为对等的 nonmember 函数实体。
    举个例子, 下面是 magnitude() 的一个 nonmember 定义:

    float magnitude3d(const Point3d *_this)
    {
        return sqrt(_this->_x *this->_x + 
                _this->_y *this->_y +
                _this->_z *this->_z);
    }

    乍看之下似乎 nonmember function 比较没有效率, 它间接地经由参数取用坐标成员, 而 member function 却是直接取用坐标成员。 但是实际上 member function 被内化为 nonmember 的形式。以下是转换步骤:
    1. 改写函数的 signature 以安插一个额外的参数到 member fucntino 中,用以提供一个存取管道, 使 class object 得以调用该函数。该额外函数被称为 this 指针:

    //non-const nonstatic member 的增长过程
    Point3d
    Point3d::magnitude(Point3d *const this)
    //如果 memberfunction 是 const, 则变成:
    //const nonstatic member 的扩张过程
    Point3d
    Point3d::magnitude(const Point3d *const this)

    2. 将每一个对 nonstatic data member 的存取操作改为经由 this 指针来存取:

    {
        return sqrt(_this->_x *this->_x + 
                _this->_y *this->_y +
                _this->_z *this->_z);
    }

    3. 将 member fucntion 重现写成一个外部函数, 对函数名称进行 mangling 处理, 使它成为程序中独一无二的语汇:

    extern magnitude__7Point3dFv(
        register Point3d *const this);

    转换好了之后其每个调用操作也需要转换, 于是:

    //你看到的
    obj.magnitude();
    //转换为
    mgnitude__7Point3dFv( &obj );
    
    //你看到的
    ptr->magnitude();
    //变成了:
    magnitude__7Point3dFv(ptr);
    
    //你看到的
    Point3d
    Point3d::normalize() const
    {
        register float mag = magnitude();
        Point3d normal;
    
        normal._x = _x / mag;
        normal._y = _y / mag;
        normal._z = _z / mag;
        return normal;
    }
    //内部转化为
    void normalize__7Point3dFv(register const Point3d *const this,
                   Point3d &__result)
    {
        register float mag = this->magnitude();
        //default constructor
        __result._x = this->_x / mag;
        __result._y = this->_y / mag;
        __result._z = this->_z / mag;
        return;
    }
    //另一个比较有效率的方法
    Point
    Point3d::normalize() const
    {
        register float mag = magnitude();
        return Point3d( _x/mag, _y / mag, _z / mag);
    }
    //这个方法会被转化为
    void
    normalize__7Point3dFv( register const Point *const this,
                Point3d &__result)
    {
        register float mag = this->magnitude();
        __result .Point3d::Point3d(
            _x/mag, _y / mag, _z / mag );
        return;
    }


    这可以节省 default constrctor 初始化所引起的负担。

  • 相关阅读:
    关于工作
    5种风格的 jQuery 分页效果【附代码】
    轮播图jquery
    Microsoft.AspNetCore.Localization 自定义多语言获取
    10-微信小程序 WXS
    9-微信小程序引用
    8-微信小程序 事件
    7-微信小程序 模板(template)
    6-微信小程序 条件渲染 wx:if
    5-微信小程序 列表渲染 wx:for
  • 原文地址:https://www.cnblogs.com/wuOverflow/p/4115274.html
Copyright © 2011-2022 走看看