所以我有一个FileReader
类,它看起来像这样:
#define DISALLOW_COPY(type) \
type(const type&); \
void operator=(const type&)
class FileReader {
FILE *file;
DISALLOW_COPY(FileReader);
protected:
unsigned char *data;
long size;
public:
FileReader(const char *filename);
~FileReader();
unsigned long getSize();
unsigned char *getFileData();
};
FileReader::FileReader(const char *filename) {
file = NULL; data = NULL;
if (!(file = fopen(filename, "rb"))) { throw std::runtime_error("File could not be opened."); }
fseek(file,0,SEEK_END);
size = ftell(file);
rewind(file);
data = new unsigned char [size];
VERIFY(size == (long)fread(data, 1, size, file));
fclose(file);
#ifdef DEBUG
PRINT("FileReader opening file "); printf("%s, %ld bytes.\n",filename,size);
#endif
}
FileReader::~FileReader() {
delete[] data;
}
unsigned char *FileReader::getFileData() { return data; }
unsigned long FileReader::getSize() { return size; }
它本身功能很好。
当我创建FileReader
时,我必须使用一个文件名来指定它必须打开的文件,当我完成它时,它会自动清理。
但是我发现我在使用这门课时遇到了一些麻烦。你看,如果我试图从另一个类中使用它,例如一个表示光栅图像的Image
类,我不是总是通过阅读它来创建一个Image
从文件。所以,我不想从FileReader
继承Image
。
我也不能让FileReader
成为Image
的成员,因为我在初始化Image
时仍需要初始化(并读出文件)。
然而,我可以做的是使用FileReader
传递Image::loadFile()
,但是我必须分配一个新缓冲区来存储所有数据,因为FileReader
将被清理在函数调用结束时。
起初我认为RAII是一个好主意,但现在,我不太确定。它非常适合处理异常,但我想防止像这样移动我的数据,同时保持一个干净的界面,这将有助于防止内存管理的噩梦。有没有办法做到这一点?在我看来,我必须对事物进行重大调整,以避免在一系列动态分配的缓冲区中处理所有数据。我应该使用智能指针吗?
答案 0 :(得分:2)
RAII IS 是个好主意。您需要拆分文件和“打开文件”对象。创建一个名为OpenFile的新类,使用如下OpenFile(FileReader& f)之类的构造函数;您的资源是一个打开的文件,而不是文件名。
答案 1 :(得分:0)
您可以使FileReader *
成为私有成员并重载您的构造函数。
public:
Image();
Image(const char* fileName);
因此,Image类的使用者决定会发生什么。在第二个构造函数中,初始化FileReader *
,然后仅在初始化时才在析构函数中销毁它。我想这可能是RAII,因为对象上的构造函数初始化了对象需要的资源。
希望这有帮助。