how do I add new methods to a class in the standard library

178 Views Asked by At

I want to extend the std::fstream class from the <fstream> header. I plan to add a couple functions like std::fsteam create(path), std::vector<std::string> read_lines(path), etc.

What Im asking is pretty simple. Instead of creating a whole new class, I want to be able to just simply add the methods in another file and then just make std::fstream objects and use those new methods.

I have two files. file_helper.hh where I will declare the methods, and file_helper.cc where I will define them and link them to my main.cc file.

So, what do I write within file_helper.hh to add these new methods to std::fstream if possible? Is it even possible?

2

There are 2 best solutions below

5
Aykhan Hagverdili On

The way to do that in C++ is to add your own free-standing functions with the functionality you want:

// stdex.h
#include <string>
#include <fstream>
#include <vector>

namespace stdex 
{
    std::vector<std::string> read_lines(std::ifstream& self);
}

And then you just use them as you would any function:

// main.cpp
#include <fstream>
#include <iostream>

#include "stdex.h"

int main()
{
    std::ifstream file{"foobar.txt"};
    for (const auto& line : stdex::read_lines(file)) {
        std::cout << line << '\n';
    }
}
0
Ted Lyngmo On

What you are describing would look something like below. Note though:

  • The functions you've suggested both take a path parameter. Having to create an instance of your fstream to be able to call create(path) or read_lines(path) doesn't make sense. These functions would be much better as free functions.
#include <filesystem>
#include <fstream>
#include <string>
#include <vector>

class myfstream : public std::fstream { // inherit from std::fstream
public:
    // make the fstream constructors and assignment operators available
    using std::fstream::fstream;
    using std::fstream::operator=;

    // example implementations of your member functions:
    std::fstream create(std::filesystem::path path) const {
        return {path, std::ios::out};
    }

    std::vector<std::string> read_lines(std::filesystem::path path) const {
        std::vector<std::string> rv(1);
        if (std::ifstream is(path); is) {
            for (; std::getline(is, rv.back()); rv.emplace_back()) {}
        }
        rv.resize(rv.size() - 1);
        return rv;
    }
};