标签:c c11 oop unique-ptr
我创建了一个从std :: istream派生的自定义istream,当文件是压缩文件时使用自定义streambuf,否则使用std :: filebuf.
#mystream.h
class my_stream: public istream {
public:
explicit my_stream(const std::string &path);
private:
std::unique_ptr<std::streambuf> b_;
}
#mystream.cpp
my_stream::my_stream(const std::string &path) :std::istream(nullptr) {
if(path.substr(path.length()-6, path.length())==".gzip"){
b_ = std::make_unique<gzipbuf>(path); //gzipbuf is derived from std::streambuf
}
else {
std::unique_ptr<std::filebuf> fb;
fb->open(path.c_str(), std::ios::in);
b_ = fb;
}
this->init(b_.get());
}
我能够在一个地方将派生类unique_ptr分配给基类unique_ptr
b_ = std::make_unique<gzipbuf>(path);
但不是另一个
b_ = fb;
它说
候选函数不可行:没有来自’unique_ptr>>’的已知转换’unique_ptr,default_delete>>’第一个论点
operator =(unique_ptr&& __u)noexcept
解决方法:
首先,在此之后
std::unique_ptr<std::filebuf> fb;
fb实际上并没有指向任何东西,它只是一个空的unique_ptr,所以你在这里调用未定义的行为:
fb->open(path.c_str(), std::ios::in);
要解决此问题,只需将行更改为:
auto fb = std::make_unique<std::filebuf>();
关于你得到的错误,如果允许这条线
b_ = fb;
然后,b_和fb都会指向同一个对象. unique_ptr不允许这样做.资源可以由one_ptr一个且唯一的一个拥有.一种解决方案是使用std :: move将所有权从fb传递给b_:
b_ = std::move(fb)
然后fb不再拥有任何东西.
就个人而言,我喜欢尽可能初始化构造函数初始化列表中的成员变量,并将streambuf的创建提取到单独的函数中,以便这样做:
std::unique_ptr<std::streambuf> createStream(const std::string &path) {
if(path.substr(path.length()-5, path.length())==".gzip"){ // I think you meant 5 here!
return std::make_unique<gzipbuf>(path);
}
auto fb = std::make_unique<std::filebuf>();
fb->open(path.c_str(), std::ios::in);
return fb;
}
那么my_stream的构造函数可以是:
my_stream::my_stream(const std::string &path) : std::istream(nullptr),
b_(createStream(path)) {
this->init(b_.get());
}
标签:c,c11,oop,unique-ptr 来源: https://codeday.me/bug/20190727/1554779.html
本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享; 2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关; 3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关; 4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除; 5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。