碰到一个从未见过的问题:
在类定义中实现函数,其中有一个返回值与实际不一致!此函数实现在CPP文件中却正常,我这个情况大概表示如下:类A:
class A
{
  A():a(100),b(200){}
  ...protected:
  ...
  int a;
  int b;
}
类B:用内联函数返回成员的值
class B :public A
{
  ...
  GetValueA() { return a; }
  GetValueB() { return b; }
}
例如
现在new一个B对象,调用GetValueB()得到的值不是200,而是固定的另一内存单元的值,
写成GetValueB() { int ret = b; return ret; } 时还是一样,
但是如果将GetValueB()实现在CPP文件中,却是正常,得到的是200。实在不知道为什么会这样,因为GetValueA(),GetValueC(),等其它的内联返回成员值却是正常的。通过调试发现是取成员b的值时位置计算错误(偏移差几字节)
汇编信息如下:
42: class CMyClientSession : public ClientSession
...
省略几行
...
61: UInt32 GetStartInSec() { return fStartPlayTimeInSec; }
62: UInt32 GetDurationInSec()
63: {
010754D0 push ebp
010754D1 mov ebp,esp
010754D3 sub esp,0C8h
010754D9 push ebx
010754DA push esi
010754DB push edi
010754DC push ecx
010754DD lea edi,[ebp-0C8h]
010754E3 mov ecx,32h
010754E8 mov eax,0CCCCCCCCh
010754ED rep stos dword ptr [edi]
010754EF pop ecx
010754F0 mov dword ptr [ebp-4],ecx
64:
65:
66: UInt32 fDur = fDurationInSec;
010754F3 mov eax,dword ptr [ebp-4]
010754F6 mov ecx,dword ptr [eax+0D6h]
010754FC mov dword ptr [ebp-8],ecx
67: return fDur; //fDurationInSec;
01075537 mov eax,dword ptr [ebp-8]
68: }断点在67行时:
eax值为0x01f00068, 为对象首地址,没错。
fDurationInSec 地址为0x01f00150, 值为 0x000000e6, 没错。
ecx值为0x0118003e(一直得到的结果是这个值),因为它是eax+0D6h单元的值,而eax+0D6h为0x01f0013e, 没有定位到fDurationInSec的正确地址0x01f00150。偏差了18个字节。
为什么内联函数得到成员的值时会产生偏差? 我在GetDurationInSec()中加上取成员fStartPlayTimeInSec也是一样的会偏差18字节,而且只有我这个GetDurationInSec()函数会这样,其它函数正常。GetDurationInSec()函数实现体写在CPP文件中时却又正常。期待高手解答。

解决方案 »

  1.   

    #include "iostream.h"
    class A
    {
    public:
    A():a(100),b(200){}
    ~A(){}

    protected: int a;
    int b;
    };class B : public A
    {
    public:
    B(){}
    ~B(){}

    inline int GetValueA() { return a; }
     inline int GetValueB() { return b; }
    };
    void main()
    {
    B* temp=new B();
    int i=temp->GetValueB();
    cout<<i<<endl;
    delete temp;
    }
    我把上面代码试了一下,输出的是200。
      

  2.   

    当把函数实现写在类内部时,便器默认的选项是inline;但是inline需要在每一个声明或者实现该函数的地方都出现inline的关键字,所以,还是加上inline吧,编译器的默认行为是不可捉摸的……每一个都有区别……