我使用std :: array来替换'指针并计算'调用某些C代码中的方法我升级到C ++。创建和使用std :: array是没有问题的,但是在销毁时它将在所有元素上调用析构函数。
但我的数组通常不是完整的,导致对空元素进行析构函数调用。通常不是问题,因为它们将使用默认构造函数构造,但我想通过递减大小计数来删除元素,这意味着要使用'使用'数组中的元素,然后导致销毁问题。
通过让析构函数调用其元素来确保只销毁数组的一部分是最好的方法吗?
对不起,我还没清楚。我创建了一个包含std :: array和size int。
的类class MyArray {
std::array< myclass, N > m_array;
unsigned int m_size;
};
显然,阵列并不总是满的。我需要一个只破坏m_array的第一个m_size元素的析构函数。
这会有用吗?
MyArray::~MyArray() {
for (unsigned int s = 0; s < m_size; ++s) {
m_array[s].~myclass();
}
}
我担心的是析构函数在myclass上被调用两次。
答案 0 :(得分:4)
这完全不可能。 std::array
只是原始数组的包装器。数组没有“满”或“空”的概念。元素同样就在那里,它们不能被“移除”,它们将被破坏。
您正在与您选择的容器类型的主要特征作斗争。你必须恢复选择。必须有无数其他方式来实现您需要的行为,例如:与std::vector
。
答案 1 :(得分:3)
从这开始:
No output has been received in the last 10 minutes
然后使用放置新手动破坏和手动破坏,在template<class T, size_t N>
struct semirray{
size_t cur=0;
std::array<std::aligned_storage_t<sizeof(T),alignof(T)>,N> buf;
};
类上实施大小调整,ctors和dtors。 buf将包含空数据,这些数据有足够的空间容纳semirray
并且正确对齐。
这是工作。
如果要更换指针和计数,请考虑使用T
。这通常占用1个指针和2个计数(或3个指针)的空间。如果您希望对象不移动,则std::vector<T>
缓冲区大小,现在.reserve(x)
是初始化大小,size()
是未初始化的大小。只要您没有通过容量,项目位置就会稳定。
如果您不关心内存中的项目位置,您甚至不必担心容量问题。
答案 2 :(得分:2)
如果你的数组并不总是满的,那么它不是一个数组,也不是一个对象数组。 N
myclass
es数组始终包含N
myclass
个es。
你可能想要一个:
std::vector<myclass>
- 一个动态大小的数组,用于跟踪其自身的所有元素,并根据需要删除它们。std::array<boost::optional<myclass>, N>>
- 一个静态大小的元素数组,可以是可选的 - 数组中的每个元素都知道它是否是一个实际的对象,如果是,则只调用~myclass()
。 鉴于此评论引出了您的问题:
我正在使用
std::array
替换某些C代码中的'指针和计数'调用方法我正在升级到C ++
我相信你想要std::vector<myclass>
。它就像一个指针和一个计数,除了方式更好。
答案 3 :(得分:0)
我相信您可以使用union
技巧。
union
不会在其成员上调用析构函数,因为它不知道要调用哪个析构函数。因此,您需要显式破坏元素。
#include <memory>
#include <cstddef>
#include <algorithm>
#include <iterator>
tmeplate<typename T, std::size_t N>
struct Partial_array
{
// Anonymous union escapes the names of its members into the outer scope
union {std::array<T, N> array_;};
std::size_t num_elements_;
// Need explicit copy / move constructors
~Partial_array()
{
// C++17
std::destroy(std::begin(array_), std::begin(array_) + num_elements_)
// C++11
std::for_each(std::begin(array_), std::begin(array_) + num_elements_,
[](const auto& element) -> void {element.~T();}
);
}
};