C ++非静态方法折叠

时间:2015-08-20 21:44:58

标签: c++

参考这个问题stackoverflow.com/q/14188612,是否有编译器折叠两个对象的方法实例化的情况?

让我们说我们有以下课程,私人"无状态"方法add,不修改类成员:

class Element
{
public:        
    Class(int a, int b) : a_(a), b_(b)
    {
        c_ = add(a, b);
    }

private:
    int add(int a, int b)
    {
        return a + b;
    }

private:
    int a_;
    int b_;
    int c_;
}

int main(void)
{
    Element a(1, 2);
    Element b(3, 4);
}

我们有时可以期望add实际上会被编译为类似static的方法吗?或者,更明确一点,a.add的地址等于b.addadd仅存储一次)。

这只是一个与理解编译器优化有关的问题。

3 个答案:

答案 0 :(得分:2)

编译器将始终add生成一个二进制方法/函数,
独立于您拥有的物体数量。其他任何事情都不是愚蠢的,但不可能:

编译器无法知道/计算运行期间仅存在多少个对象。虽然可以使用您的示例,但更复杂的程序将根据运行时给出的输入(键盘,文件......)实例化变量(或不变量)。

请注意,模板可以导致多代,一个代码用于代码中使用的每种模板类型(但为此,代码足以了解所有内容,并且它与对象计数无关)。

答案 1 :(得分:0)

在类定义中定义方法时,通常意味着该方法应该内联到每个调用者中。编译器可以选择不这样做,但通常你可能会发现该方法实际上并不存在于输出程序中(当然,在调试版本中不是这样)。

答案 2 :(得分:0)

对于非内联成员函数,标准说

  

程序中最多应有一个非内联成员函数的定义

C ++ b.adda.add中没有实体可以从中获取地址。 address-of运算符需要对C::m(...)形式的成员函数使用qualified-id来获取函数的地址。在您的情况下,add的地址是

   auto ptr = &Element::add;

并且独立于任何实例。这给出了一个成员函数指针,它只能用于与一个对象一起调用该函数,例如如果add是公共方法,则(a.*ptr)(0,1)(b.*ptr)(2,3)