参考这个问题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.add
(add
仅存储一次)。
这只是一个与理解编译器优化有关的问题。
答案 0 :(得分:2)
编译器将始终为add
生成一个二进制方法/函数,
独立于您拥有的物体数量。其他任何事情都不是愚蠢的,但不可能:
编译器无法知道/计算运行期间仅存在多少个对象。虽然可以使用您的示例,但更复杂的程序将根据运行时给出的输入(键盘,文件......)实例化变量(或不变量)。
请注意,模板可以导致多代,一个代码用于代码中使用的每种模板类型(但为此,代码足以了解所有内容,并且它与对象计数无关)。
答案 1 :(得分:0)
在类定义中定义方法时,通常意味着该方法应该内联到每个调用者中。编译器可以选择不这样做,但通常你可能会发现该方法实际上并不存在于输出程序中(当然,在调试版本中不是这样)。
答案 2 :(得分:0)
对于非内联成员函数,标准说
程序中最多应有一个非内联成员函数的定义
C ++ b.add
或a.add
中没有实体可以从中获取地址。 address-of运算符需要对C::m(...)
形式的成员函数使用qualified-id来获取函数的地址。在您的情况下,add的地址是
auto ptr = &Element::add;
并且独立于任何实例。这给出了一个成员函数指针,它只能用于与一个对象一起调用该函数,例如如果add是公共方法,则(a.*ptr)(0,1)
或(b.*ptr)(2,3)
。