getter的成本是否为零

Does a getter have zero cost?

本文关键字:是否 getter      更新时间:2023-10-16

我有一个简单的类:

class A {
    public:
    int get() const;
    private:
    void do_something();
    int value;
}
int A::get() const {
    return value;
}

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

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

当方法不是虚方法时,编译器可以对其进行优化。好的编译器(链接时间优化)可以优化,即使方法不是inline,并在单独的。cpp文件中定义。不太好的只能这样做,如果它是在类定义内声明,或在头文件与inline关键字。对于虚拟方法,这取决于,但很可能没有。

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

如果getter被定义为内联函数(要么通过在类中隐式地定义它,要么通过inline关键字显式地定义它),编译器通常会将其内联,并且调用它时不会有开销。

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

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

首先,如果您不返回引用而不是值

,则无法在对象中操作值:
int& get();

现在它返回一个引用,并且可以被修改。但我认为这不是很清楚,您还应该定义一个setter并使用它回写修改后的值:

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

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