直接使用get方法或成员访问值?

时间:2014-08-25 16:57:54

标签: c++ function class member

class SomeClass
{
    int classMember;
    public:
    int GetMember();
    bool IsPositive();
};

int SomeClass::GetMember()
{
   return classMember;
}

bool SomeClass::IsPositive()
{
    int val = GetMember();  //Case#1. Accessing value using get method
    int val = classMember;  //Case#2. Accessing value directly

    return (val > 0);
}

问题:使用案例#1是否优于案例#2,反之亦然?与成员直接相比,使用get方法是否有任何开销(甚至是最小的)?

3 个答案:

答案 0 :(得分:1)

答案是,这实际上取决于编译器如何选择执行某些操作。查看是否存在差异的最佳方法是查看反汇编。

    int val = classMember;
010C4869  mov         eax,dword ptr [this]  
010C486C  mov         ecx,dword ptr [eax]  
010C486E  mov         dword ptr [val],ecx  

    return val > 0;
010C4871  cmp         dword ptr [val],0  
010C4875  jle         SomeClass::IsPositiveClassMember+20h (010C4880h)  
010C4877  mov         dword ptr [ebp-4],1  
010C487E  jmp         SomeClass::IsPositiveClassMember+27h (010C4887h)  
010C4880  mov         dword ptr [ebp-4],0  
010C4887  mov         al,byte ptr [ebp-4]

VS

    int val = GetMember();
010C4829  mov         ecx,dword ptr [this]  
010C482C  call        SomeClass::GetMember (010C1168h)  
010C4831  mov         dword ptr [val],eax  

    return val > 0;
010C4834  cmp         dword ptr [val],0  
010C4838  jle         SomeClass::IsPositiveGetMember+23h (010C4843h)  
010C483A  mov         dword ptr [ebp-4],1  
010C4841  jmp         SomeClass::IsPositiveGetMember+2Ah (010C484Ah)  
010C4843  mov         dword ptr [ebp-4],0  
010C484A  mov         al,byte ptr [ebp-4]  

第二个示例调用SomeClass::GetMember,它有自己的反汇编。所以在第二种情况下,它不是只从成员加载值,而是进行函数调用。

    return classMember;
010C4817  mov         eax,dword ptr [this]  
010C481A  mov         eax,dword ptr [eax]  

您需要注意的是,使用classMember值加载val的指令是相同的,因此开销来自Call SomeClass::GetMember

然而,这是debug模式,没有优化。如果我们优化并构建版本,我们会看到以下反汇编:

    int val = classMember;

    return val > 0;
013D4830  xor         eax,eax  
013D4832  cmp         dword ptr [ecx],eax  
013D4834  setg        al  

VS

    int val = GetMember();

    return val > 0;
013D4820  xor         eax,eax  
013D4822  cmp         dword ptr [ecx],eax  
013D4824  setg        al  

编译器优化了调用,没有区别。

答案 1 :(得分:0)

它完全取决于程序员的需要。

何时创建功能?

  1. 增加程序的模块性
  2. 重复执行某些常见任务时。
  3. 在你的情况下,假设要添加两个号码。

    为此您可以使用

    int a= data member 1 + data member 2
    

    假设您必须在许多地方使用它。

    然后你考虑了第2点。

    您可以创建像addnumber()这样的功能,以方便使用和阅读。

    关于表现,

    两者都是相同的,因为member function are inline by default在类定义中定义时。因此,不需要单独的堆栈分配来调用该函数

答案 2 :(得分:0)

使用GetMember()可能会慢一些,除非它由编译器显式或隐式地内联。

但是,使用访问器可以极大地帮助您进行调试,暂时改变它:

int SomeClass::GetMember()
{
   return classMember;
}

进入这个:

int SomeClass::GetMember()
{
   std::cout << "GetMember() called when classMember=" << classMember << std::endl;
   return classMember;
}

但这可能有点老了。