2012-02-21 62 views
5

我想将具有保存发送到它的数据的函数的类设置为文本文件。可以传递给它的数据可以像一个std::stringintdoublefloatunsigned int等任何东西,也可以是:std::vector<T>T[]std::vector<std::vector<T>>T[][]用于数组,向量,内置类型的C++模板函数STL

现在,显然如果它是一个数组,我需要遍历它才能将数据发送到文本文件。我想使用模板,但我不知道如何做数组。

这是要走的路吗?

class CMyClass 
{ 
    template<typename T> 
    void SaveData(T data); 
    void SaveData(std::vector<T> data); 
    void SaveData(std::string data); 
    void SaveData(T* data);    // Perhaps I'll also need to pass in the size. 
    void SaveData(std::vector<std::vector<T>> data); 
    void SaveData(T** data); 
}; 

我想象的std::string代码是相同的代码,std::vector<T>提供T是类型内置(像intfloat或东西)。

然后我相应地编写SaveData(...)的每个函数?

+0

您的标题非常宽泛和模糊,您可能想要重新修饰它。 – 2012-02-21 06:55:19

+4

供参考:http://www.boost.org/doc/libs/1_48_0/libs/serialization/doc/index.html – Anycorn 2012-02-21 06:55:52

回答

5

首先,你可以在模板类或函数。既然你想要做阵列,你必须去后者的选项。举例如下:

class CMyClass 
{ 
public: 
    template<typename T> void SaveData(const T &data); 
    template<typename T, size_t N> void SaveData(const T (&data)[N]); 
    template<typename T, size_t N, size_t M> void SaveData(const T (&data)[N][M]); 
    template<typename T> void SaveData(const std::vector<T> &data); 
    template<typename T> void SaveData(const std::vector<std::vector<T> > &data); 
    void SaveData(const std::string &data); 
}; 

一旦你定义的功能,下面的例子说明如何称呼他们:

int i; 
int i1[5]; 
int i2[5][7]; 
std::vector<int> v1; 
std::vector<std::vector<int> > v2; 
std::string s; 

CMyClass saveClass; 

saveClass.SaveData<int>(i); 
saveClass.SaveData<int>(i1); 
saveClass.SaveData<int>(i2); 
saveClass.SaveData<int>(v1); 
saveClass.SaveData<int>(v2); 
saveClass.SaveData(s); 

根据您的要求,您可以使类单和功能静,省略了需要在所有实例CMyClass和简单地调用功能如下:

CMyClass::SaveData<int>(i); 
CMyClass::SaveData<int>(i1); 
CMyClass::SaveData<int>(i2); 
CMyClass::SaveData<int>(v1); 
CMyClass::SaveData<int>(v2); 
CMyClass::SaveData(s); 

注:

  1. 参数也应该是引用(即, “&数据”而不是“数据”),因此每次调用函数时只传递引用而不是执行整个容器的副本。
  2. 我已经明确声明函数为public,假设这是完整的类,它的函数将被另一个类访问。默认情况下,一个类的成员是私人的。
  3. 确保每个嵌套的“>”之间有空格。

祝你好运!

+0

谢谢你做得太多!这真的有帮助。我有一个问题,为什么你用数组而不是数据?它只是一个命名的东西,或者它是否做了一些事情,因为我只是在VS中看到它做了一些事情。 – 2012-02-21 13:10:17

+0

我使用“数组”作为变量名称只是习惯的一种力量。我编辑了代码,以便它现在是“数据”来维护接口一致性。别担心,“数组”不是C++中的关键字。对不起,可能造成的任何混淆! – athwaites 2012-02-21 14:12:14

+0

谢谢最后一个问题,为了实现std :: vector >,我不得不再次进行单独的重载,我不会,尽管事实上该方法可能与std ::矢量>? – 2012-02-21 21:59:19

0

我相信你在一个类中混合了两件事情,应该避免这样做:据我所知,你的类是关于什么(它的“责任”)是将数据写入文件。你添加的另一件事是关于迭代数据集合的知识。

看看STL的<algorithm>方法:

http://www.cplusplus.com/reference/algorithm/

那里你可以找到迭代数据,例如通用方式在find方法:

template<class InputIterator, class T> 
    InputIterator find (InputIterator first, InputIterator last, const T& value) 
    { 
    for (;first!=last; first++) if (*first==value) break; 
    return first; 
    } 

这使你从您是否使用vectorlist,数组或任何独立。

如果您还想序列化诸如vector<vector<T> >(请注意两个>!之间的空格!),您必须更多地解释如何处理此类数据。简单地连接元素,就好像所有T都在一个vector?在这种情况下,你可能会尝试创建一个新的迭代器来完成这件事。

升压迭代器库可以在这方面帮助:

http://www.boost.org/doc/libs/1_48_0/libs/iterator/doc/index.html

+0

感谢您的建议。详细说明一下,我想以这种方式将任何传入的内容写入文本文件:ifstream ifs(“test.txt”,ifstream :: in); ifs <<数据。如果数据是一个向量,那么我必须迭代它,如果数据是一个整数,那么我不会。如果数据是T [] [],那么我也必须迭代...我知道std :: algorithm和函数,如for_each(...);然而,我不明白他们会如何帮助,如果用户传入一个int或char。此外,我不相信我可以使用std :: for_each来处理像std :: vector >这样的东西。 – 2012-02-21 07:16:05