How do I manage file descriptors and sockets with RAII?

Managing file descriptors and sockets with RAII (Resource Acquisition Is Initialization) in C++ ensures that resources are properly released when they go out of scope, preventing memory leaks and resource exhaustion. The principle behind RAII is to associate resource management with object lifetime. By wrapping file descriptors and sockets in RAII-style classes, you can ensure automatic cleanup.

In this example, we will create a simple RAII class that manages a file descriptor:

class FileDescriptor {
    int fd;

public:
    FileDescriptor(const char* path, int flags) {
        fd = open(path, flags);
        if (fd == -1) {
            throw std::runtime_error("Failed to open file");
        }
    }

    ~FileDescriptor() {
        if (fd != -1) {
            close(fd);
        }
    }

    int get() const { return fd; }

    // Delete copy constructor and assignment operator
    FileDescriptor(const FileDescriptor&) = delete;
    FileDescriptor& operator=(const FileDescriptor&) = delete;
};

// Usage
int main() {
    try {
        FileDescriptor fd("example.txt", O_RDONLY);
        // Use fd.get() to read from the file
    } catch (const std::exception& e) {
        std::cerr << e.what() << '\n';
    }
}

RAII file descriptor management resource management C++ sockets automatic cleanup C++ RAII classes