2011-10-24 65 views
5

我有一个简单的类:吸气剂是否有零成本?

class A { 
    public: 
    int get() const; 

    private: 
    void do_something(); 
    int value; 
} 

int A::get() const { 
    return value; 
} 

吸气功能简单明了。吸气者将使用它们,所以在do_something中,我应该使用get()以访问value。我的问题是:编译器是否会优化getter,所以它将等同于直接访问数据?或者如果我直接访问它,我仍然会获得性能(这意味着更糟糕的设计)?

A::do_something() 
{ 
    x = get(); 
    // or... 
    x = value; 
} 
+0

真正的问题当然是:*它有关系吗?因为如果没有,那么谁在乎呢?如果是这样,那么只有你可以检查你的特定编译器是否执行优化。 –

回答

7

当方法不是虚拟的,编译器可以优化它。即使方法不是inline并在单独的.cpp文件中定义,也可以优化编译器(使用链接时优化)。如果在类定义中声明的话,或者在关键字为inline的头文件中声明的不是那么好。对于虚拟方法,这取决于,但很可能不是。

+0

不错,提到'虚拟'的事情。 – iammilind

+3

对于虚函数,它取决于编译器是否知道动态类型。虽然虚拟函数的最常见使用会导致不能使用的上下文,但也有例外,并且我知道至少有一个依赖于编译器内联虚拟函数的习惯用法。 –

3

编译器几乎肯定会内联这样一个微不足道的getter,如果它有权访问定义。

+0

它是否通过在类之外定义它来内联没有'inline'关键字的getter? – ks1322

+0

@ ks1322:成员函数的类内定义被隐式声明为“inline”。 – Nawaz

+0

@Nawaz,我问它会在这种特殊情况下内联(没有'inline'关键字,成员函数被定义**在类的外部**)? – ks1322

2

如果getter被定义为内联函数(通过在类内部定义它,或者用关键字inline明确定义),编译器通常会内联它,并且在调用它时没有开销。

然而,调试版本禁用内联是很常见的,这是完全有效的,因为编译器不需要内联任何东西。

1

那么,使用get通常是一个更好的设计,因为它隐藏了获取值所涉及的实际逻辑(今天是一个领域,明天它可能需要更复杂的逻辑)。至于性能,访问值本身至少会像get一样快,但编译器很可能会内联该调用。

1

首先,你将无法操纵内部你的对象的价值如果不返回引用而不是值:

int& get(); 

现在它返回一个参考,可以被改变。但恕我直言,这是不是很干净,你也应该定义一个setter,并用它来写回改变值:

int get() const; 
void set(int); 

... 
A::do_something() 
{ 
    x = get(); 
    set(value); 
} 

二传手的性能取决于你的编译器。大多数现代编译器能够内联简单的getter/setter,所以不应该有任何性能损失。