【发布时间】:2017-05-29 22:53:32
【问题描述】:
我有一门课叫
Array<T>
您可以创建任何类型的数组。
template <typename T>
class Array
{
private:
T *m_array;
int m_size;
...
例如,
Array <int> myArray(32)
是一个大小为 32 的 int 类型的数组。它可以存储基本类型或复杂对象。例如,
Array<Monster> monsters(32)
可以容纳一组怪物对象。无论使用哪种类型,我都想从磁盘保存和加载阵列。
其中一个对象,比如 Actor,有一个 std::string 类型的成员变量(名称)。因此,它存储为
Array<Actor> actors(32)
我今天意识到 C 的 I/O 函数对 std::string 一无所知,因此从文件加载 std::string 会导致关闭时崩溃。我想将我的保存/加载功能升级到 C++ 的等效功能。我的假设是这将解决我保存和加载具有 std::string 类型成员变量的对象的问题。
我原来的保存/加载功能: (由于模板的工作方式,它们位于标题中,我应该提到它们更正式地是 Array 或 Array::save() 和 Array::load() 的成员。)
bool save(const string filename)
{
FILE *fOut = NULL;
int written = 0;
// Validate the array
if (!isValidArray())
return false;
// Open the file
fOut = fopen(filename.c_str(), "wb");
if (fOut == NULL)
return false;
// Write the array's size to file.
fwrite(&m_size, sizeof(int), 1, fOut);
// Write the array to file.
written = fwrite(m_array, sizeof(T), m_size, fOut);
fclose(fOut);
// Validate if the array was written correctly
if (written != m_size)
return false;
return true;
}
加载:
bool load(const string filename)
{
FILE *fIn = NULL;
int read = 0;
int size = 0;
// Open the file
fopen_s(&fIn, filename.c_str(), "rb");
if (fIn == NULL)
return false;
// Read the array's size from file.
fread(&size, sizeof(int), 1, fIn);
// Rleease the old array
release();
// Initialize the new array
if (!init(size))
return false;
// Read the array from file.
read = fread(m_array, sizeof(T), size, fIn);
fclose(fIn);
// Validate if the array was written correctly.
// If not, clean up the array object.
if (read != size)
{
if (m_array != NULL)
{
delete[] m_array;
m_array = NULL;
m_size = 0;
}
return false;
}
return true;
}
总的来说,我想将这些转换为 C++ 的文件处理。
这是我对 save() 的 C++ 尝试:
bool save(const string filename)
{
ofstream fOut;
// Validate the array
if (!isValidArray())
return false;
// Open the file
fOut.open(filename.c_str(), std::ios::binary | std::ios::out);
if (!fOut.is_open())
return false;
// Write the array's size to file.
fOut << m_size;
// Write the array to file. ????
fOut.write(m_array, m_size);
fOut.close();
return true;
}
所以,我的问题是当它的模板类型可能是基本数据类型、结构或类时,如何将数组保存到文件中。我的第一个假设是:
// Write the array to file. ????
fOut.write(m_array, m_size);
任何想法都会有所帮助。谢谢。
发现我需要序列化,我为我的 Actor 类重载了 operator
std::ofstream & X2D::operator<<(std::ofstream & output, const Actor & p)
{
// insert magical code here
return output;
}
【问题讨论】:
-
你要找的东西叫做序列化。
-
“由于模板的工作方式,它们位于标题中” 顺便说一句,您应该考虑将这些定义移出类定义,以使代码更清晰和更好。它们仍然可以在标题中。
-
“我有一个名为 [..] 的类,你可以创建任何类型的数组。”
std::array有什么问题? -
这个问题相当于“如何在 C++ 中序列化任意类型的数据?”尽管这是一个非常广泛的问题(您是否研究过任何选择?),但基本上可以回答“您没有”。
-
唯一可以任意序列化的类型是 POD 类型。您可以使用模板来处理这种情况。对于非 POD 类型,我假设它们为序列化提供了适当的
operator<<。由于您的容器提供了保存操作,因此您可以将容器记录为要求其元素定义正确的operator<<以进行序列化。