这可能听起来很愚蠢,但C ++和C ++ 11在它可以达到的魔力方面让我感到惊讶。也许这太过分了,但我更愿意确认我的恐惧,而不是假设它们。
是否有可能以任何方式强制转换std :: future或std :: future_shared对象?
我发现如果我描述我遇到的具体问题通常会有所帮助。我本质上是异步加载一些音频和视频,虽然我已经开始使用std :: async,我发现它非常有用,但直到现在我还没有使用过期货。它本质上是从我身上学到的,期货似乎能很好地处理异常,我想让我的异步加载更加强大。我的糟糕程序偶尔会耗尽内存,但在异步调用启动之前,程序不会发生这种情况。解决内存问题完全是另一个问题,目前还不是一个可行的解决方案。
无论如何 - 我有两个独立的对象来处理音频(AudioLibrary)和视频(VideoLibrary)的加载,但由于它们共享许多共性,它们都从相同的基础对象(BaseLibrary)继承。
每个相应库返回的音频和视频都有自己的音频容器(AudioTrack)和视频(VideoTrack),它们也从公共对象(BaseTrack)继承。
我确定你可以看到它的发展方向。我想在BaseLibrary中进行一些常规异常处理,它将具有一些虚拟函数,如loadMedia。这些将被派生库覆盖。这样麻烦就开始了。我读到指针对象(如unique_ptr或shared_ptr)不能协变,所以只创建一个虚拟方法并不能解决它。
然而,我希望通过虚拟功能,我仍然可以以某种方式达到我想要的效果。
实现以下内容的BaseLibrary:
std::shared_future<BaseTrack> BaseLibrary::loadMedia()
std::shared_future<BaseTrack> BaseLibrary::loadMediaHelper()
然后AudioLibrary将实现
std::shared_future<AudioTrack> AudioLibrary::loadAudio()
此函数使用BaseLibrary中的函数但返回其自己的特定类型的AudioTrack,而不是BaseTrack。
这一切都可能吗?
更新1:
感谢评论和回答,我看到了如何实现我的目标,但我还有一些未解决的问题。我认为通过非常明确地解决这些问题会更容易。我实际上正在使用shared_ptrs,因为许多对象正在使用加载的音频和视频,所以我有以下类型的defs:
typedef std::shared_ptr<BaseTrack> BaseTrackPtr;
typedef std::shared_ptr<AudioTrack> AudioTrackPtr;
AudioTrack当然继承自BaseTrack。根据给定的建议,我有一个可编译(缩写)的代码结构,对于BaseLibrary如下:
class BaseLibrary {
virtual std::shared_future<BaseTrackPtr> loadMedia();
virtual std::shared_future<BaseTrackPtr> loadMediaHelper() = 0;
}
std::shared_future<BaseTrackPtr> BaseLibrary::loadMedia()
{
// Place code to catch exceptions coming through the std::future here.
// Call the loadMediaHelper via async - loadMediaHelper is overwritten in the inherited libraries.
}
AudioLibrary:
class AudioLibrary : public BaseLibrary {
public:
virtual std::shared_future<AudioTrackPtr> loadAudio();
protected:
virtual std::shared_future<BaseTrackPtr> loadMediaHelper();
}
std::shared_future<AudioTrackPtr> AudioLibrary::loadAudio()
{
std::shared_future<BaseTrackPtr> futureBaseTrackPtr = loadMedia();
return std::async( std::launch::deferred, [=]() {
return AudioTrackPtr( std::static_pointer_cast<AudioTrack>( futureBaseTrackPtr.get() ) );
} );
}
std::shared_future<BaseTrackPtr> AudioLibrary::loadMediaHelper()
{
// Place specific audio loading code here
}
这种结构允许我在一个地方捕获任何视频/音频加载异常,并且还返回正确的音频/视频对象而不是需要重新制作的基础对象。
我目前的两个问题如下:
答案 0 :(得分:2)
所以你有类似的东西:
class BaseLibrary
{
public:
virtual ~BaseLibrary() {}
virtual std::shared_future<std::unique_ptr<BaseTrack>> loadMedia() = 0;
};
class AudioLibrary : public BaseLibrary
{
public:
std::shared_future<AudioTrack> loadAudio();
std::shared_future<std::unique_ptr<BaseTrack>> loadMedia() override;
};
所以你可以像这样实现loadMedia()
:
std::shared_future<std::unique_ptr<BaseTrack>> AudioLibrary::loadMedia()
{
auto futureAudioTrack = loadAudio();
return std::async(std::launch::deferred,
[=]{
std::unique_ptr<BaseTrack> res =
make_unique<AudioTrack>(futureAudioTrack.get());
return res;
});
}