内联函数的问题,请高手来解答一下,

karlfly 2010-07-05 11:18:15
碰到一个从未见过的问题:
在类定义中实现函数,其中有一个返回值与实际不一致!此函数实现在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文件中时却又正常。

期待高手解答。
...全文
98 点赞 收藏 4
写回复
4 条回复
切换为时间正序
请发表友善的回复…
发表回复
hitrose27 2010-07-05
当把函数实现写在类内部时,便器默认的选项是inline;

但是inline需要在每一个声明或者实现该函数的地方都出现inline的关键字,

所以,还是加上inline吧,编译器的默认行为是不可捉摸的……

每一个都有区别……
回复
xgPaul 2010-07-05
#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。
回复
雪影 2010-07-05
lz代码中的内联函数没什么问题啊
回复
jameshooo 2010-07-05
在你的类B里面也有一个叫做b的成员变量吧
回复
发动态
发帖子
VC/MFC
创建于2007-09-28

1.5w+

社区成员

VC/MFC相关问题讨论
申请成为版主
社区公告
暂无公告