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

时间:2014-01-23 18:37:19

标签: c++ language-lawyer

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

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

1 个答案:

答案 0 :(得分:6)

如果在C ++中,代码是一流的值,那么成员函数的代码就只是一个const static类成员,你不会再期望在实例中找到它而不是你想要的任何其他静态数据成员。 (第9.4.2节:“静态数据成员不是类的子对象的一部分。”)

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

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

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

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