gpt4 book ai didi

C++ 禁止自动初始化和销毁

转载 作者:塔克拉玛干 更新时间:2023-11-03 00:13:14 25 4
gpt4 key购买 nike

如何抑制类型的自动初始化和销毁​​? T buffer[100] 自动初始化 buffer 的所有元素,并在它们超出范围时销毁它们,这很棒,但这不是我想要的行为。

#include <iostream>

static int created = 0,
destroyed = 0;

struct S
{
S()
{
++created;
}
~S()
{
++destroyed;
}
};

template <typename T, size_t KCount>
class fixed_vector
{
private:
T m_buffer[KCount];
public:
fixed_vector()
{
// some way to suppress the automatic initialization of m_buffer
}

~fixed_vector()
{
// some way to suppress the automatic destruction of m_buffer
}
};

int main()
{
{
fixed_vector<S, 100> arr;
}

std::cout << "Created:\t" << created << std::endl;
std::cout << "Destroyed:\t" << destroyed << std::endl;
return 0;
}

这个程序的输出是:

Created:    100
Destroyed: 100

我希望它是:

Created:    0
Destroyed: 0

我唯一的想法是使 m_buffer 成为一些像 char 这样简单构造和破坏的类型,然后依靠 operator[] 来包装指针数学对我来说,虽然这似乎是一个可怕的黑客解决方案。另一种解决方案是使用 mallocfree,但这提供了我不想要的间接级别。


我想要这个的原因是因为我正在制作一个容器,我不想为我不会使用的东西支付初始化开销。例如,如果我的 main 函数是:

int main()
{
{
std::vector<S> vec;
vec.reserve(50);
}

std::cout << "Created:\t" << created << std::endl;
std::cout << "Destroyed:\t" << destroyed << std::endl;
return 0;
}

输出是正确的:

Created:    0
Destroyed: 0

最佳答案

你可能想看看 boost::optional

template <typename> struct tovoid { typedef void type; };

template <typename T, size_t KCount, typename = void>
struct ArrayStorage {
typedef T type;
static T &get(T &t) { return t; }
};

template <typename T, size_t KCount>
struct ArrayStorage<T, KCount, typename tovoid<int T::*>::type> {
typedef boost::optional<T> type;
static T &get(boost::optional<T> &t) {
if(!t) t = boost::in_place();
return *t;
}
};

template <typename T, size_t KCount>
class Array
{
public:
T &operator[](std::ptrdiff_t i) {
return ArrayStorage<T, KCount>::get(m_buffer_[i]);
}

T const &operator[](std::ptrdiff_t i) const {
return ArrayStorage<T, KCount>::get(m_buffer_[i]);
}

mutable typename ArrayStorage<T, KCount>::type m_buffer_[KCount];
};

对类类型进行了专门化,将它们包装到一个optional中,从而延迟调用构造函数/析构函数。对于非类类型,我们不需要包装。不包装它们意味着我们可以将 &a[0] 视为连续的内存区域,并将该地址传递给需要数组的 C 函数。 boost::in_place 将就地创建类类型,而不使用临时的 T 或其复制构造函数。

不使用继承或私有(private)成员允许类保持聚合,允许一种方便的初始化形式

// only two strings are constructed
Array<std::string, 10> array = { a, b };

关于C++ 禁止自动初始化和销毁,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2662417/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com