非外行类数组
Array of uninitalized classes
本文关键字:数组 更新时间:2023-10-16
我想在不调用构造函数的情况下在堆栈上分配和类数组。以下示例阐明了:
template<class t,int SetNum> class set
{
private:
t Storage[SetNum];
};
class myClass
{
private:
int* Array;
public:
myClass()
{
Array=new int[10];
}
}
int main()
{
set<myClass,10> Set;
}
我不想为调用myClass
的构造函数时发生的Array
分配 10 个新整数,但仍然希望为myClass
分配空间。
你必须有一个unsigned char
数组(或类似数组)来用作元素的"后备存储",然后调用放置new
运算符(参见此处)来构造你的实例(顺便说一下,这是std::vector
已经做的事情)。
警告: 如果使用放置 new,则有责任手动释放使用它创建的对象,显式调用析构函数;此外,传递给放置 new 的指针必须与正在创建的对象正确对齐,否则可能会发生不好的事情。
另请参阅此问题。
使用所述技术构建的std::array
和std::vector
扭曲混合的示例(需要 C++11 才能使union
技巧起作用):
#include <cstddef>
#include <memory>
#include <stdexcept>
#include <iostream>
template<typename T, std::size_t N>
class array_noinit
{
union storage_helper
{
private:
// this member assures that the storage is properly aligned
T t;
public:
unsigned char storage[sizeof(T)*N];
// needed because T's constructor/destructor is implicitly deleted
storage_helper() { };
~storage_helper() { };
};
storage_helper s;
std::size_t _size;
T * _storage;
public:
array_noinit() :
_size(0), _storage((T*)s.storage)
{}
~array_noinit()
{
while(_size>0)
pop_back();
}
void push_back(const T & elem)
{
if(_size>=N)
throw std::runtime_error("Not enough capacity.");
new(_storage+_size) T(elem);
_size++;
}
void pop_back()
{
if(_size>0)
{
_size--;
_storage[_size].~T();
}
}
T & at(std::size_t Idx)
{
if(Idx>=_size)
throw std::out_of_range("Idx out of range.");
return _storage[Idx];
}
std::size_t size() const
{
return _size;
}
std::size_t capacity() const
{
return N;
}
};
class A
{
int _i;
public:
A(int i) : _i(i)
{
std::cout<<"In A constructor - "<<_i<<"n";
}
A(const A & right)
: _i(right._i)
{
std::cout<<"In A copy constructor - "<<_i<<"n";
}
~A()
{
std::cout<<"In A destructor - "<<_i<<"n";
}
};
int main()
{
std::cout<<"With intsn";
array_noinit<int, 4> arr;
arr.push_back(1);
arr.push_back(2);
arr.push_back(3);
arr.push_back(4);
for(std::size_t i=0; i<4; i++)
std::cout<<arr.at(i)<<" ";
std::cout<<"n";
std::cout<<"With a class - we don't add anythingn";
array_noinit<A, 10> arr2;
std::cout<<"With a class - now we add stuffn";
array_noinit<A, 10> arr3;
arr3.push_back(A(1));
arr3.push_back(A(2));
arr3.push_back(A(3));
return 0;
}
输出:
With ints
1 2 3 4
With a class - we don't add anything
With a class - now we add stuff
In A constructor - 1
In A copy constructor - 1
In A destructor - 1
In A constructor - 2
In A copy constructor - 2
In A destructor - 2
In A constructor - 3
In A copy constructor - 3
In A destructor - 3
In A destructor - 3
In A destructor - 2
In A destructor - 1
编辑有一种更简单的方法来获得对齐的存储。
相关文章:
- Mongodb c++驱动程序:如何查询元素的数组
- 将数组的地址分配给变量并删除
- 从C++本机插件更新Vector3数组
- lambda参数转换为constexpr技巧,然后获取带链接的数组
- 将数组作为参数传递给函数安全吗?作为第三方职能部门,可以探索他们想要的之外的其他元素
- 数组索引的值没有增加
- 将对象数组的引用传递给函数
- 为char数组调整zlib-zpipe
- 2D数组来自文本输入,中间有空格
- std::向量与传递值的动态数组
- 在c++中用vector填充一个简单的动态数组
- 使用strcpy将char数组的元素复制到另一个数组
- 使用指针从C++中的数组中获取最大值
- C++使用整数的压缩数组初始化对象
- 告诉一个 const char 数组,除了编译时 C 样式的字符串外,它不以 '