3.3 数据成员的存取

本节的讨论针对两种情况的效率进行分析:

class X
{
    public:
        //数据成员mem
        static double mem;
};

X orgin;
X * pt = &orgin;

//考虑以下两种情况各自的存取效率

orgin.mem = 0.0;  //case1
pt->mem = 0.0;    //case2

Q1:mem是静态数据成员

• 每个静态数据成员都将被提出类之外,且只有一个实例,每次使用静态成员时,就被内部转换为对该唯一实例的直接操作

• 通过类对象访问静态成员只是一种文法上的妥协,(如x.static_member),此时静态成员并不在类中,存取静态成员并不需要通过类对象

• 对继承与虚基类等情况也是相同的处理,因为只有一个实例,同样能是直接存取其路径

• 对于通过函数调用静态数据成员的情况,cfront编译器的操作是直接抛弃该函数调用,而C++标准则明确要求函数必须被求值,虽然结果可能无用,如:

Eg:

        func().mem;  //X func()

        *Ubuntu对函数进行求值

• 若取一个静态成员的地址会得到一个指向其数据类型的指针,而不是一个指向类成员的指针,因为静态类成员并不在类对象中,如:

Eg:

class X
        {
            static const int static_member = 10;
        };

        &X::static_member;

        //得到类型如下的内存地址为:
         double*;
        而不是:
        double X::*;

结论:对静态成员的存取操作 case1 与 case2 效率相同

Q2:mem是非静态成员

• 对一个非静态数据成员进行存取操作,编译器需要把类对象的起始地址加上数据成员的偏移位置

• 对非静态成员的存取操作的执行效率在该成员是一个struct 成员、类成员、单一继承或多重继承的情况下,case 1 与 case 2都完全相同

• 但若该成员是虚基类的成员时,将会有重大的差异

• 若该类是一个虚基类的派生类,且存取的成员是虚基类的成员,此时分析如下:

1) 对 case 1,此时类对象的类型确定是 X,即使类 X 继承自虚基类,成员的偏移位置在编译时就确定了,因此可以直接进行存取

2) 对 case 2,此时 pt s所指向的类类型无法确定,因此就不知道成员的偏移位置,所以此时存取操作将延迟执行期,经由一个额外的简介引导,才能进行存取操作
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值