Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/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++ 将派生类唯一\u ptr分配给基类唯一\u ptr_C++_Oop_C++11_Unique Ptr - Fatal编程技术网

C++ 将派生类唯一\u ptr分配给基类唯一\u ptr

C++ 将派生类唯一\u ptr分配给基类唯一\u ptr,c++,oop,c++11,unique-ptr,C++,Oop,C++11,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_; }

我创建了一个从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());
}
上面说

candidate function not viable: no known conversion from 'unique_ptr<std::filebuf, default_delete<std::basic_filebuf<char>>>' to 'unique_ptr<std::basic_streambuf<char>, default_delete<std::basic_streambuf<char>>>' for 1st argument
      operator=(unique_ptr&& __u) noexcept
候选函数不可行:第一个参数没有从'unique_ptr'到'unique_ptr'的已知转换
运算符=(唯一\u ptr&&\u_)无例外

首先,在这行之后

std::unique_ptr<std::filebuf> fb;
要解决此问题,只需将行更改为:

auto fb = std::make_unique<std::filebuf>();
然后,
b
fb
都会指向同一个对象。
unique\u ptr
不允许这样做。一个资源只能由一个
unique\u 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;
}

您需要移动它:
b=std::move(fb)因为这里只能有一个(没有副本)。谢谢!这是有道理的。
auto fb = std::make_unique<std::filebuf>();
b_ = fb;
b_ = std::move(fb)
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(const std::string &path) : std::istream(nullptr),
  b_(createStream(path)) {
    this->init(b_.get());
}