加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – 将派生类unique_ptr分配给基类unique_ptr

发布时间:2020-12-16 10:03:15 所属栏目:百科 来源:网络整理
导读:我创建了一个从std :: istream派生的自定义istream,当文件是压缩文件时使用自定义streambuf,否则使用std :: filebuf. #mystream.hclass my_stream: public istream { public: explicit my_stream(const std::string path); private: std::unique_ptrstd::str
我创建了一个从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());
}

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读