写作课——很好的练习

Writing classes - good practice

本文关键字:练习 很好      更新时间:2023-10-16

首先,我并不想在堆栈代码交换上发布这个代码,因为这是在大约5分钟内编写的一小部分代码。

我想问你我写的这个类(我第一个用c++写的)是否可以接受。我并没有真正看过很多c++代码,所以我无法将其与任何东西进行比较。

但是我见过一些类只实现函数声明,这些函数的内部是在代码的其他地方写的。

如果你觉得有什么地方不对,我想征求你的意见。为什么他们会像我在上面一段描述的那样呢?哪一种编码风格更好?

class File {
private:
    FILE *_handler;
    char *_path;
    long _size;
    void setHandler(char *mode)
    {
        this->_handler = fopen(this->_path, mode);
    }
public:
    File(char *path)
    {
        this->_path = path;
    }
    size_t read()
    {
        this->setHandler("r");
        char *buffer = (char*) malloc(sizeof(char)*this->_size);
        return fread(buffer, 1, this->_size, this->_handler);
    }
    void write(char *data)
    {
        this->setHandler("w");
        fputs(data, this->_handler);
    }
    long size()
    {
        if(! sizeof(this->_size) > 0)
        {
            fseek(this->_handler, 0, SEEK_END);
            this->_size = ftell(this->_handler);
            rewind(this->_handler);
        }
        return this->_size;
    }
}; // End File

这里有技术问题,我认为是基本的设计问题。

技术:

你打开一个文件多少次?你关了几次?看看read()和write()是怎么做的

错误处理在哪里?如果fopen()失败会发生什么。不要不检查就使用返回值。

基本设计问题:

你分配内存,谁释放它?将分配和释放的责任分开通常不是一个好主意。c++开发者倾向于使用智能指针来帮助实现这一点。

如果给定一个非常大的文件,你的代码会怎么做?

最基本的是:你的界面是一个"你必须记住这个"的界面。如果有人调用read()而没有记住先调用size(),会发生什么?为什么打电话的人需要这么做?设计接口的目的是让调用者的生活变得简单。

如果没有歧义,则不需要使用this

File(char *path)
{
    _path = path;
}

函数也是一样你可以去掉this

size_t read()
{
    setHandler("r");
    char *buffer = (char*) malloc(sizeof(char)*_size);
    return fread(buffer, 1, _size, _handler);
}

在类声明中实现函数有它的用途,但它不是必须的(除非使用模板),你可以在源文件中定义函数,并从那里包含你的类头文件。这使得类实现与类接口分离。

假设你在头文件中改变了一个函数的实现,包括这个头文件在内的所有文件,即使它们不使用这个函数,也需要重新编译。

由于你正在使用c++,你可能想看看使用c++文件对象(fstream,ifstream,ofstream等)。

最后,我真的看不出像这样包装文件的意义,除非你的类提供了一些额外的功能,你在这里所做的只是改变了函数的名称,并创建了另一个抽象层,这并没有带来太多的表