I need to store the data in three different ways: 1. storing the data to a `std::string` 2. write the data to a given file descriptor 3. both of the above And I hope to use a uniform interface for these three different methods. How to make it better? Here is the [code snippet](https://godbolt.org/z/h8nW8zd4n): ``` #include <memory> #include <string> #include <iostream> #include <unistd.h> class DataStorage { public: DataStorage()=default; DataStorage(const DataStorage&) = default; DataStorage(DataStorage&&) = default; DataStorage& operator(const DataStorage&) = default; DataStorage& operator(DataStorage&&) = default; virtual int Store(const char *buffer, int count) = 0; virtual ~DataStorage(){}; }; class DataStorageByStr : virtual public DataStorage { public: DataStorageByStr(std::string &str) : str_(str), total_count_{0}{}; DataStorageByStr()=delete; DataStorageByStr(const DataStorageByStr&) = default; DataStorageByStr(DataStorageByStr&&) = default; DataStorageByStr& operator(const DataStorageByStr&) = default; DataStorageByStr& operator(DataStorageByStr&&) = default; int Store(const char *buffer, int count) { str_ += std::string(buffer, count); total_count_ += count; return 0; }; int GetTotalWritten() const {return total_count_;}; private: std::string &str_; int total_count_; }; class DataStorageByFd : virtual public DataStorage { public: DataStorageByFd(int &fd):fd_(fd), total_count_{0}{}; int Store(const char *buffer, int count) { int ret = write(fd_, buffer, count); if(ret > 0) { total_count_ += ret; } return ret; }; int GetTotalWritten() const {return total_count_;}; private: int &fd_; int total_count_; }; class DataStorageByStrAndFd : public DataStorageByStr, public DataStorageByFd { public: DataStorageByStrAndFd(std::string &str, int &fd):DataStorageByStr(str), DataStorageByFd(fd){} DataStorageByStrAndFd()=default; DataStorageByStrAndFd(const DataStorageByStrAndFd&) = default; DataStorageByStrAndFd(DataStorageByStrAndFd&&) = default; DataStorageByStrAndFd& operator(const DataStorageByStrAndFd&) = default; DataStorageByStrAndFd& operator(DataStorageByStrAndFd&&) = default; int Store(const char *buffer, int count) { int ret1 = DataStorageByStr::Store(buffer, count); int ret2 = DataStorageByFd::Store(buffer, count); return ((0==ret1) && (0==ret2))?0:-1; } int GetWrittenByStr() const {return DataStorageByStr::GetTotalWritten();} int GetWrittenByFd() const {return DataStorageByFd::GetTotalWritten();} }; int StoreSomeData(DataStorage &storage, const std::string data_to_store) { return storage.Store(data_to_store.data(), data_to_store.length()); } int main() { { std::cout << "==============1=============" <<std::endl; std::string str{"storing the string to std::string works !"}; std::string data; DataStorageByStr storage_by_str = DataStorageByStr(data); DataStorage &storage = storage_by_str; StoreSomeData(storage, str); std::cout << data << std::endl; std::cout << "total written by str:" << storage_by_str.GetTotalWritten() << std::endl; } { std::cout << "==============2=============" <<std::endl; std::string str{"storing the string to fd works !"}; int fd = 1; DataStorageByFd storage_by_fd = DataStorageByFd(fd); DataStorage &storage = storage_by_fd; StoreSomeData(storage, str); std::cout << std::endl << "total written by fd:" << storage_by_fd.GetTotalWritten() << std::endl; } { std::cout << "==============3=============" <<std::endl; std::string str{"thanks for your attention for this matter!"}; std::string data; int fd = 1; DataStorageByStrAndFd storage_by_str_and_fd = DataStorageByStrAndFd(data, fd); StoreSomeData(storage_by_str_and_fd, str); std::cout << std::endl; std::cout << "string length:" << str.length() << std::endl; std::cout << "total written by string:" << storage_by_str_and_fd.GetWrittenByStr() << std::endl; std::cout << "total written by fd:" << storage_by_str_and_fd.GetWrittenByFd() << std::endl; } } ```