C++使用整数的压缩数组初始化对象

C++ initialize objects with packed array of integers

本文关键字:数组 初始化 对象 压缩 整数 C++      更新时间:2023-10-16

我有一个这样的类:

#define MYNUM 4
class myClass {
private:
char myData[MYNUM];
public:
myClass(char myArr[MYNUM]) {
for (int i = 0; i < MYNUM; i++) myData[i] = myArr[i];
}
};

我想初始化一个myClass对象数组,如下所示:

static myClass obj_arr[5] = { {1, 1, 1, 1}, {2, 2, 2, 2}, {3, 3, 3, 3}, {4, 4, 4, 4}, {5, 5, 5, 5} };

但我得到了error: too many initializers。有没有一种方法可以按照我想要的方式初始化obj_arr数组?

首先,在现有构造函数中,char myArr[MYNUM]参数与传递char myArr[]相同,后者与char *myArr相同。IOW,构造函数将一个简单的指针作为输入,因此它实际上并不能确保输入数组是真正的MYNUM元素。要做到这一点,您需要通过引用而不是通过指针来传递数组。

至于您想要的初始化类型,请添加一个以std::initializer_list作为输入的构造函数。

试试这个:

#include <initializer_list>
class myClass {
private:
char myData[MYNUM];
public:
myClass(char (&myArr)[MYNUM]) {
for (size_t i = 0; i < MYNUM; ++i) myData[i] = myArr[i];
}
myClass(std::initializer_list<char> myList) {
for (size_t i = 0; (i < myList.size()) && (i < MYNUM); ++i) myData[i] = myList.begin()[i];
for (size_t i = myList.size(); i < MYNUM; ++i) myData[i] = 0;
}
};

实时演示

不能像那样将数组作为函数参数传递。您确实有几个选项可以获得您想要的初始化语法:

通过公开myData,使myClass成为聚合:

constexpr size_t MYNUM = 4;
class myClass {
public:
char myData[MYNUM];
};

实时演示

C++允许使用大括号初始化直接初始化聚合类的成员。这是标准库的std::array模板使用的路径。如果你的类有其他你想保密的数据成员,这显然是行不通的。

使用std::initializer_list<char>

constexpr size_t MYNUM = 4;
class myClass {
private:
char myData[MYNUM];
public:
myClass(std::initializer_list<char> myList)
{
// Initialize first elements of myData with the parameters passed
for (size_t i = 0; i < std::min(myList.size(), MYNUM); ++i) {
myData[i] = myList.begin()[i];
}
// Fill out any missing elements with 0
for (size_t i = myList.size(); i < MYNUM; ++i) {
myData[i] = 0;
}
}
};

实时演示

这将用于初始化私有类成员,并且它支持大括号初始化。如果没有像C++处理大括号初始化数组的默认方式那样提供,它甚至会零填充尾部元素。它唯一的缺点是,如果给出的元素比myClass想要的多,它就不会产生错误。

模板

constexpr size_t MYNUM = 4;
class myClass {
private:
char myData[MYNUM];
public:
template <typename... Ts>
myClass(Ts... args)
: myData{static_cast<char>(args)...}
{
}
};

实时演示

这是最接近于使用私有类成员的聚合初始化方法的方法。myClass的构造函数不接受用于初始化myData的容器,而是接受数量可变的参数,并使用它们直接初始化myData。如果提供的参数少于MYNUM,则这将使尾随元素为零初始化,如果提供了多于MYNUM的参数,则将产生编译时错误。

利用嵌套for循环将数组的元素(由const.ref传递(分配给成员变量。

#include <iostream>
#define MYNUM 4
class myClass {
private:
int myData[MYNUM][MYNUM];
public:
myClass();
myClass(const int (&myArr)[MYNUM][MYNUM]){
for(int i = 0; i < MYNUM; i++){
for(int j = 0; j < MYNUM; j++){
myData[i][j] = myArr[i][j]; 
}
}
}
void printmyData(){
for(int i = 0; i < MYNUM; i++){
std::cout << "{";
for(int j = 0; j < MYNUM; j++){
std::cout << myData[i][j];
}
if (i < MYNUM){ 
std::cout << "}";
if (i < MYNUM-1){
std::cout << ",";
std::cout << " ";
}
}
}
std::cout << std::endl;
}
};
int main () {
int mainArr[MYNUM][MYNUM] = {{1, 2, 3, 4}, {5, 6, 7, 8}, {4, 3, 2, 1}, {8, 7, 6, 5}};
myClass obj = myClass(mainArr);
obj.printmyData();
return 0;
}