C&C++   发布时间:2022-04-03  发布网站:大佬教程  code.js-code.com
大佬教程收集整理的这篇文章主要介绍了c – 创建非默认可构造类的虚拟对象大佬教程大佬觉得挺不错的,现在分享给大家,也给大家做个参考。
tl; dr:我想构造一个包含泛型类型Value成员的类ListEntry,但Value不是认构造的,ListEntry不知道如何构造它.我永远不会访问这个Value成员,所以没有初始化它并不重要.

为什么我这样做

我正在实现一个大致类似于以下内容的双链表

template<class Value>
class ListEntry {
  Value value;
  ListEntry<Value> *prev;
  ListEntry<Value> *next;
};
template<class Value>
class List {
  ListEntry<Value> senTinel;
};

列表条目之间的链接总是形成一个闭合的圆圈,其中senTinel将最后一个列表元素连接到第一个列表元素.使用senTinel.prev =& senTinel和senTinel.next =& senTinel初始化senTinel对象.

这样,我摆脱了很多特殊情况,我永远不必检查nullptr,因为没有空指针.将元素添加到列表的末尾(在最后一个元素和senTinel之间)不是特殊情况,但与在两个真实元素之间的列表中间添加元素相同.

因此,在所有实际列表条目中,值字段将包含列表条目的实际值.对于它们,我可以通过在其构造函数中赋予它一个Value对象来初始化ListEntry,因此我不需要Value是认的可构造的.在哨兵中,永远不会访问值字段.但不幸的是,由于Value不是认构造的,编译器不允许我创建senTinel对象.

我可以使ListEntry中的value成员成为指针,boost :: optional或类似的东西.由于性能问题,我不喜欢这样.
关于如何在没有性能/内存成本的情况下在ListEntry中存储Value并且不需要Value可认构造的任何想法?在我看来,必须有一种获取Value对象而不调用其构造函数方法.

解决方法@H_419_19@
使用原始缓冲区和新位置:
template<class Value>
class ListEntry {
  alignas(value) char storage[sizeof(value)];
  ListEntry<Value> *prev;
  ListEntry<Value> *next;
};

构建价值:

new (entry->storagE) Value(/* params */);

破坏价值:

reinterpret_cast<Value*>(entry->storagE)->~Value();

大佬总结

以上是大佬教程为你收集整理的c – 创建非默认可构造类的虚拟对象全部内容,希望文章能够帮你解决c – 创建非默认可构造类的虚拟对象所遇到的程序开发问题。

如果觉得大佬教程网站内容还不错,欢迎将大佬教程推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。小编QQ:384754419,请注明来意。