C++作为标准是否禁止在单个类实例中存储成员函数?

Lig*_*ica 19 c++ language-lawyer

在C++实现中,通常代码不会(以任何形式)存储在类实例中.代码段与对象等不在同一存储空间中.这意味着成员函数不会"存储"在类实例中.

但是当有人问到这个问题时,我想知道:在多大程度上,如果有的话,标准是否禁止将成员函数存储在其封装类中,以至于实例化该类会复制这些函数?从理论上讲,我可以通过这种方式实现一个实现吗?甚至可以远程遵守常见的ABI?

ric*_*ici 6

如果在C++中,代码是第一类值,那么成员函数的代码将只是一个const static类成员,并且您不会期望在实例中找到它而不是任何其他静态数据成员.(§9.4.2:"静态数据成员不是类的子对象的一部分.")

但是,代码不被视为一个值,而且你甚至不能构造一个指向成员函数的指针(虽然你可以构造一个"指向成员的指针",这实际上不是指针,因为它没有引用实例就不可用).这使得成员函数代码与静态数据成员和非成员函数都不同,这两者都允许创建独立指针,这些指针还具有(或多或少)排除复制的相等保证.

类实例确实包含对虚拟成员函数的引用(间接地,在大多数实现中;指针实际上是指静态vtable),在创建新实例时必须复制它.没有要求引用的大小,所以理论上(据我所知),没有什么可以阻止实现避免间接并为类的每个实例重新存储整个代码.

但是标准布局类型有一个例外,它是没有虚拟成员函数的类的子集,在第9.12/18节中表达,它要求具有相同初始成员的两个标准布局类型具有相同的初始成员布局.回顾标准布局对象必须可以简单地用memcpy(§3.9/ 3)复制,在内存中必须是连续的(§1.8/ 5),并且必须按顺序包含它们的成员(§9.12/ 13),这个要求使它有效不可能在任何标准布局对象中包含特定于类的静态数据,其中包括成员函数的代码.

因此,我得出结论,至少对于标准布局对象,C++标准确实禁止在对象表示中存储静态数据,包括成员函数的代码.