【问题标题】:CRTP call child function in destructor of parentCRTP 在父的析构函数中调用子函数
【发布时间】:2019-06-09 17:33:08
【问题描述】:

我有两个这样的类(简化代码以更清楚地显示问题):

template<typename stream_type>
class Stream : public std::basic_streambuf<char, std::char_traits<char>>
{
private:
    std::string pBuffer;

    //other functions overridden here..

public:
    Stream();
    virtual ~Stream();

    Stream(const Stream& other) = delete;
    Stream& operator = (const Stream& other) = delete;
};

template<typename stream_type>
Stream<stream_type>::Stream() : pBuffer()
{
    parent_type::setg(nullptr, nullptr, nullptr);
    parent_type::setp(nullptr, nullptr);
}

template<typename stream_type>
Stream<stream_type>::~Stream()
{
    //Parent Destructor calling child member function..
    static_cast<stream_type*>(this)->sync(&pBuffer[0], pBuffer.size());
}


//CRTP Child..
template<typename char_type>
class File : public Stream<File<char_type>>
{
private:
    FILE* hStream;

public:
    File(const char* path) : Stream<File<char_type>>()
    {
        hStream = fopen(path, "w");
    }
    ~File()
    {
        //Child destructor is closing the file..
        fclose(hStream);
    }

    int sync(const char_type* data, std::size_t size)
    {
        if (fwrite(data, sizeof(char_type), size, hStream) == size)
        {
            fflush(hStream);
        }

        return traits_type::eof();
    }
};

问题:

当孩子的析构函数由于超出范围而被调用时,它首先关闭文件..之后,它调用父析构函数..但父级仍在尝试访问孩子的“同步”函数(当然这是一个错误)..

关于如何解决这种情况的任何想法?我需要父类来保证其缓冲区中的所有数据都同步到磁盘。但是,我的子类可能并不总是一个“文件”类。它可能是另一种不同步的流。我需要父类强制所有子类同步他们的数据。

有什么想法可以做到吗?

【问题讨论】:

  • 这里似乎只需要交换父类和子类即可。或者更确切地说,引入某种负责同步的基类
  • "但是,我的子类可能并不总是 File 类。它可能是另一种不同步的流。我需要父类强制所有子类同步他们的数据。”这不是自相矛盾吗?尽管如此,如果某些孩子不同步,感觉同步是File 不流式传输的一部分。为什么不希望在 ~File 中同步?
  • 你需要File间接派生自std::basic_streambuf&lt;char, std::char_traits&lt;char&gt;&gt;吗?你还需要Stream 从那个类派生吗?如果您可以更改类层次结构或使用包含代替或除了继承之外,可能还有一些替代方案。

标签: c++ c++11 iostream streambuf


【解决方案1】:

成员和基地按照它们创建的相反顺序被销毁。
因此,一种解决方案可能是在FILE* 周围有一个包装类,并且有
作为比Stream 更早的基础,以便它在以后被销毁;

template<typename char_type>
class File : private CFileWrapper, public Stream<File<char_type>>

【讨论】:

    猜你喜欢
    • 2021-12-11
    • 1970-01-01
    • 2018-01-31
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-06
    • 1970-01-01
    相关资源
    最近更新 更多