Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/templates/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 需要使用模板解决运行时多态性的帮助吗_C++_Templates_Polymorphism_Raii - Fatal编程技术网

C++ 需要使用模板解决运行时多态性的帮助吗

C++ 需要使用模板解决运行时多态性的帮助吗,c++,templates,polymorphism,raii,C++,Templates,Polymorphism,Raii,我已经有一段时间的模板包装了一个C库文件*。它是指向文件*包装器类的共享指针的相当经典的实现。使用我自己的自定义共享指针背后的原因是为一些C库文件*自由函数提供自由函数替换,以便允许我直接替换使用文件*的遗留代码 我的实现使用了一个内部包装器,它保证删除时,所拥有的文件*被关闭。拉伊 但是,我需要创建一个类似的系统来处理以下情况:我希望底层文件*被刷新和截断,而不是在最后一个文件*持有者被销毁时关闭。也就是说,我有一个打开的文件*是保证关闭的原始类型,但希望将该文件*的无主副本分发给另一个对象,

我已经有一段时间的模板包装了一个C库文件*。它是指向文件*包装器类的共享指针的相当经典的实现。使用我自己的自定义共享指针背后的原因是为一些C库文件*自由函数提供自由函数替换,以便允许我直接替换使用文件*的遗留代码

我的实现使用了一个内部包装器,它保证删除时,所拥有的文件*被关闭。拉伊

但是,我需要创建一个类似的系统来处理以下情况:我希望底层文件*被刷新和截断,而不是在最后一个文件*持有者被销毁时关闭。也就是说,我有一个打开的文件*是保证关闭的原始类型,但希望将该文件*的无主副本分发给另一个对象,该对象将保证在最后一个实例被销毁时,它将刷新并截断该文件*而不是关闭它,从而使我的底层文件*处于打开状态,但是流的内容被刷新到磁盘,文件大小只反映有效内容

对于编译时多态性,我已经简单地解决了这个问题。但是我需要一些方法来提供运行时多态性,我真的不想在这个场景中再添加一层间接性,也就是说,如果我使用指向自动关闭或自动刷新文件*包装器的多态指针,我会是金色的——但我真的想保持现在的深度,并在自定义共享指针实现中隐藏多态性

基本上,如果我有:

template <class WrapperT>  
class FilePointerT  
{  
public:
  // omitted: create, destroy, manipulate the underlying wrappered FILE*  
private:
  WrapperT * m_pFileWrapper;  
  ReferenceCount m_rc;  
}
显然,大量细节被遗漏了。只需说,当这些对象中的最后一个被删除时,它会删除最后一个m_pFileWrapper事实上,如果我重写这段代码,我可能会使用boost::shared_ptr

不管怎么说,这里真正的问题是,我很难理解如何让一个FilePointerT的wrapper可以变化,但可以在代码中使用,就好像它们都是一样的,毕竟它们是一样的,因为wrapper的实现对FilePointerT的结构和接口没有任何影响,而FilePointerT本质上是一个pimpl

我可以声明什么可以为任何包装器保存任何FilePointerT


或者,如何更改FilePointerT的定义以允许我提供特定的包装器?

您不能简单地使用std::shared\u ptr吗?为自由函数提供普通重载,没有有趣的模板错误。

你不能简单地使用std::shared\u ptr吗?为自由函数提供普通重载,没有有趣的模板错误。

您可以使用它透明地处理所有版本的FilePointerT。正如上面的海报所提到的,我也会选择共享\u ptr方法,事实上,删除程序甚至不是共享\u ptr签名的一部分,因此您可以在保持类型不变的同时更改删除程序。

您可以使用它透明地处理所有版本的FilePointerT。正如上面的海报所提到的,我也会选择共享\u ptr方法,事实上,删除程序甚至不是共享\u ptr签名的一部分,因此您可以在保持类型不变的同时更改删除程序。

值得一提的是,我最终做的是将包装器嵌入到FilePointer类中,而不是将其作为其类型的一部分

class FilePointer
{
public:
    // create using a file wrapper (which will handle policy issues)
    FilePointer(FileWrapper * pfw) : m_pFileWrapper(pfw) { }

protected:
    FileWrapper *   m_pFileWrapper; // wrapper has close/flush policy
    ReferenceCount  m_references;   // reference count
};
然后,文件指针将实际工作委托给包装器,包装器实现所需的策略,并且可以编写代码来使用文件指针


显然还有其他方法可以做到这一点,但我就是这么做的。

出于价值考虑,我最终要做的是将包装器嵌入到FilePointer类中,而不是使其成为其类型的一部分

class FilePointer
{
public:
    // create using a file wrapper (which will handle policy issues)
    FilePointer(FileWrapper * pfw) : m_pFileWrapper(pfw) { }

protected:
    FileWrapper *   m_pFileWrapper; // wrapper has close/flush policy
    ReferenceCount  m_references;   // reference count
};
然后,文件指针将实际工作委托给包装器,包装器实现所需的策略,并且可以编写代码来使用文件指针


显然还有其他方法可以做到这一点,但我就是这么做的。

+1表示类型擦除,这就是共享的\u ptr解决方案的工作方式和原因。+1表示类型擦除,这就是共享的\u ptr解决方案的工作方式和原因。