所以我有一个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
。所以,我不想从Image
继承FileReader
。
我也不能让FileReader
成为Image
的成员,因为我在初始化我的Image
时仍需要初始化(并读出文件)。
我能做些什么,但是,是在传递Image::loadFile()
使用FileReader
,但我必须分配一个新的缓冲区来存储所有数据,因为FileReader
将在函数调用结束时清理。
起初我以为RAII是一个好主意,但现在,我不太确定。处理异常很好,但我想阻止像这样移动数据,同时保持一个干净的界面,这将有助于防止内存管理恶梦。有没有办法做到这一点?在我看来,我必须对事物进行重大调整,以避免在一系列动态分配的缓冲区中混杂所有数据。我应该使用智能指针吗?
为什么不根据你拥有的对象和他们的行为建立你的对象模型,而不是基于你已经实现的一个类,并且即使它不适合你的需要也不想重建? – littleadv
你确定你已经理解了RAII的目的吗? –
如果你要在不同的类之间移动指针,它最好使用智能指针而不是原始指针。这样你就不用担心释放这些指针所获取的资源,智能指针会为你处理这些。 –