在The "Empty Member" C++ Optimization是以下代码片段:
// Listing 4: A Better Way to Eliminate Bloat
template <class T, class Alloc = allocator<T> >
class list {
. . .
struct Node { . . . };
struct P : public Alloc {
P(Alloc const& a) : Alloc(a), p(0) { }
Node* p; // Why also encapsulate a Node pointer?
};
P head_;
public:
explicit list(Alloc const& a = Alloc())
: head_(a) { . . . }
. . .
};
此实现的目的主要是避免在 Alloc
情况下对象膨胀。类没有数据成员(如默认的 allocator
类),但此特定实现的一个重要的值得注意的好处是防止(任意)Alloc
之间潜在的名称冲突类和 list
的成员类。
代码片段下方的评论通过以下说明对此进行了总结:
Now, list<> members get storage by saying "head_.allocate()", and mention the first list element by saying "head_.p". This works perfectly, there's no unnecessary overhead of any kind, and users of list<> can't tell the difference.
我理解了这个评论的第一部分,即P
中的接口(interface)封装。上课所以list<>
成员(member)必须调用head_.allocate()
获取存储空间。
但是,我不明白此评论的第二部分 - 为什么有必要(或有益)包含 Node
类中的指针 P
这样list<>
成员通过说 head_.p
来提及第一个列表元素(而不是让 p
直接成为 list<>
的成员)?这与封装Alloc
的接口(interface)有关吗?类(class)?
为什么封装接口(interface)的嵌套类有一个指向Node
的指针, 而不是顶级类?
最佳答案
在这种情况下,sizeof(list)
将是 sizeof(P)
,希望它是 sizeof(Node*)
。如果 Alloc
类型为空,它的空间使用将被优化掉。
现在考虑以下替代方案。
class list {
struct Node { . . . };
struct P : public Alloc {
P(Alloc const& a) : Alloc(a), p(0) { }
};
Node* head_pointer;
P thing_with_allocator;
}
在这种情况下,sizeof(list)
将为 sizeof(Node*) + sizeof(P)
。空基类优化在这里真的帮不上忙,因为,即使 P
现在是一个空类,它也没有被用作基类,所以它不能进行空基类优化:它的大小至少为 1。
关于c++ - 为什么分配器接口(interface)封装嵌套类的 "list"实现也受益于封装节点?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15591520/