CRTP 在 parent 的析构函数中调用 child 函数
CRTP call child function in destructor of parent
我有两个 class 结构如下(简化代码以更清楚地显示问题):
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();
}
};
问题:
当 child 的析构函数由于超出范围而被调用时,它首先关闭文件。之后,它调用 parent 析构函数..但是 parent 仍在尝试访问 child 的 "sync" 函数(当然这是一个错误)..
关于如何解决这种情况的任何想法?我需要 parent class 来保证其缓冲区中的所有数据都同步到磁盘。但是,我的 child class 可能并不总是 "file" class。它可能是另一种不同步的流。我需要 parent class 强制所有 children 同步他们的数据。
有什么办法可以做到吗?
成员和基地的销毁顺序与创建顺序相反。
所以一种解决方案可能是在 FILE*
周围有一个包装器 class,并有
作为比 Stream
更早的基地,所以它会在以后被摧毁;
template<typename char_type>
class File : private CFileWrapper, public Stream<File<char_type>>
我有两个 class 结构如下(简化代码以更清楚地显示问题):
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();
}
};
问题:
当 child 的析构函数由于超出范围而被调用时,它首先关闭文件。之后,它调用 parent 析构函数..但是 parent 仍在尝试访问 child 的 "sync" 函数(当然这是一个错误)..
关于如何解决这种情况的任何想法?我需要 parent class 来保证其缓冲区中的所有数据都同步到磁盘。但是,我的 child class 可能并不总是 "file" class。它可能是另一种不同步的流。我需要 parent class 强制所有 children 同步他们的数据。
有什么办法可以做到吗?
成员和基地的销毁顺序与创建顺序相反。
所以一种解决方案可能是在 FILE*
周围有一个包装器 class,并有
作为比 Stream
更早的基地,所以它会在以后被摧毁;
template<typename char_type>
class File : private CFileWrapper, public Stream<File<char_type>>