C++ 如何在不知道属性具有哪些构造函数的情况下初始化属性?
我需要实现以下类:C++ 如何在不知道属性具有哪些构造函数的情况下初始化属性?,c++,templates,generic-programming,C++,Templates,Generic Programming,我需要实现以下类: template <class Element, class Compare = std::equal_to<Element>> class UniqueArray { Element* data; unsigned int size; unsigned int max_size; public: explicit UniqueArray(unsigned int size); UniqueArray(const
template <class Element, class Compare = std::equal_to<Element>>
class UniqueArray {
Element* data;
unsigned int size;
unsigned int max_size;
public:
explicit UniqueArray(unsigned int size);
UniqueArray(const UniqueArray& other);
~UniqueArray();
UniqueArray& operator=(const UniqueArray&) = delete;
unsigned int insert(const Element& element);
bool getIndex(const Element& element, unsigned int& index) const;
const Element* operator[] (const Element& element) const;
bool remove(const Element& element);
unsigned int getCount() const;
unsigned int getSize() const;
};
模板
类唯一数组{
元素*数据;
无符号整数大小;
无符号整数最大值;
公众:
显式UniqueArray(无符号整数大小);
UniqueArray(常量UniqueArray和其他);
~UniqueArray();
UniqueArray&运算符=(const UniqueArray&)=删除;
无符号整数插入(常量元素和元素);
bool getIndex(常量元素和元素,无符号整数和索引)常量;
常量元素*运算符[](常量元素和元素)常量;
布尔删除(常量元素和元素);
无符号int getCount()常量;
无符号int getSize()常量;
};
问题是我不能假设元素
有一个default构造函数。
假设我看不到元素
类的实现,这意味着可能还有其他构造函数,但我不知道有多少参数以及它们的类型。
如何初始化UniqueArray的数据属性
例如,元素可以是一个点,该点有一个带两个参数的构造函数(并且没有default构造函数)
但问题是我不知道发送的是哪个元素,也不知道这个元素有什么构造函数。
代码应该是泛型的。不清楚构造函数
UniqueArray(unsigned int size)
应该做什么-默认构造那么多元素还是保留存储
如果它只保留存储,那么您可以使用将存储分配与对象构造分离,并让UniqueArray
的用户创建元素:
template <class Element, class Compare = std::equal_to<Element>>
class UniqueArray {
using storage_type = typename std::aligned_storage<sizeof(Element), alignof(Element)>::type;
storage_type* data;
unsigned int size;
unsigned int max_size;
public:
explicit UniqueArray(unsigned int size) : size(0), max_size(size) {
data = new storage_type[size];
}
~UniqueArray() {
for (unsigned pos = 0; pos < size; ++pos) {
// note: needs std::launder as of C++17
reinterpret_cast<Element*>(&data[pos])->~Element();
}
delete[] data;
}
Element& operator[](unsigned pos) {
// note: needs std::launder as of C++17
return *reinterpret_cast<Element*>(&data[pos]);
}
void insert(const Element& element) {
new (&(*this)[size++]) Element(element); // placement-new
}
// ...
};
struct A {
int a, b;
A(int x) : a(x), b(x + 5) {}
};
int main() {
UniqueArray<A> arr(3);
arr.insert({ 2 });
std::cout << arr[0].b << std::endl; // prints "7"
}
模板
类唯一数组{
使用storage\u type=typename std::aligned\u storage::type;
存储类型*数据;
无符号整数大小;
无符号整数最大值;
公众:
显式UniqueArray(无符号整数大小):大小(0),最大大小(大小){
数据=新存储类型[大小];
}
~UniqueArray(){
用于(无符号pos=0;pos~Element();
}
删除[]数据;
}
元素和运算符[](未签名的位置){
//注意:从C++17开始需要std::launder
返回*重新解释铸件(和数据[pos]);
}
无效插入(常量元素和元素){
新建(&(*this)[size++])元素(Element);//放置新建
}
// ...
};
结构A{
INTA,b;
A(intx):A(x),b(x+5){}
};
int main(){
唯一阵列arr(3);
arr.insert({2});
std::cout不清楚构造函数UniqueArray(unsigned int size)
应该做什么-默认构造许多元素还是保留存储
如果它只保留存储,那么您可以使用将存储分配与对象构造分离,并让UniqueArray
的用户创建元素:
template <class Element, class Compare = std::equal_to<Element>>
class UniqueArray {
using storage_type = typename std::aligned_storage<sizeof(Element), alignof(Element)>::type;
storage_type* data;
unsigned int size;
unsigned int max_size;
public:
explicit UniqueArray(unsigned int size) : size(0), max_size(size) {
data = new storage_type[size];
}
~UniqueArray() {
for (unsigned pos = 0; pos < size; ++pos) {
// note: needs std::launder as of C++17
reinterpret_cast<Element*>(&data[pos])->~Element();
}
delete[] data;
}
Element& operator[](unsigned pos) {
// note: needs std::launder as of C++17
return *reinterpret_cast<Element*>(&data[pos]);
}
void insert(const Element& element) {
new (&(*this)[size++]) Element(element); // placement-new
}
// ...
};
struct A {
int a, b;
A(int x) : a(x), b(x + 5) {}
};
int main() {
UniqueArray<A> arr(3);
arr.insert({ 2 });
std::cout << arr[0].b << std::endl; // prints "7"
}
模板
类唯一数组{
使用storage\u type=typename std::aligned\u storage::type;
存储类型*数据;
无符号整数大小;
无符号整数最大值;
公众:
显式UniqueArray(无符号整数大小):大小(0),最大大小(大小){
数据=新存储类型[大小];
}
~UniqueArray(){
用于(无符号pos=0;pos~Element();
}
删除[]数据;
}
元素和运算符[](未签名的位置){
//注意:从C++17开始需要std::launder
返回*重新解释铸件(和数据[pos]);
}
无效插入(常量元素和元素){
新建(&(*this)[size++])元素(Element);//放置新建
}
// ...
};
结构A{
INTA,b;
A(intx):A(x),b(x+5){}
};
int main(){
唯一阵列arr(3);
arr.insert({2});
标准::cout首先,收集要求:
- “
std:equal_to
是我唯一可以从标准库中使用的东西”
- 有一个
max\u size
和一个size
成员,getCount()
返回当前大小和getSize()
最大大小(旁注:这是可怕的)
因此我假设类的构造函数应该分配足够的内存来保存元素类的大小(参数)对象
这样做的正确方法是——建议使用<代码> STD::AigigndIsAsdio/Cuth>。因为这是一个大学作业,而你的讲师/教授/写这篇作业的人可能不知道足够的C++来关心/理解你可能最好的问题:
//在构造函数中,我重复一遍,这太可怕了!
max_size=size;//不过最好使用成员初始化
数据=重新解释转换(新的无符号字符[sizeof(元素)*最大大小];
插入时,使用“新放置”将新元素创建为副本:
new(数据[新元素的索引])元素(元素);
对于擦除,您需要手动调用析构函数
数据[索引到擦除]。~Element();
我重复一遍:这不是在实际应用程序中编写此类代码的方式!它不会教您任何有价值的东西!首先,收集需求:
- “
std:equal_to
是我唯一可以从标准库中使用的东西”
- 有一个
max\u size
和一个size
成员,getCount()
返回当前大小和getSize()
最大大小(旁注:这是可怕的)
因此我假设类的构造函数应该分配足够的内存来保存元素类的大小(参数)对象
按照中的建议,正确的方法是使用std::aligned_storage
。因为这是一个大学家庭作业,你的讲师/教授/撰写此作业的人