为什么我可以有一个std::vector<std::ofstream*>而不是std::vector<std::ofstream>?

Why can I have a std::vector<std::ofstream*> but not a std::vector<std::ofstream>?

本文关键字:std ofstream gt lt vector 我可以 有一个 为什么      更新时间:2023-10-16

我有以下测试代码,其中我有一个参数fS,它是ofstream s的容器:

    #include <fstream>
    #include <vector>
    #include <cstdlib>
    #include <cstdio>
    int main()
    {
        // my container of ofstream(s)
        std::vector<std::ofstream> fS;
        // instantiate an ofstream
        std::ofstream of("myfile.txt");
        // push back to my container
        fS.push_back(of);
        return 0;
    }

这根本无法编译。然而,当我将ofstream的容器更改为指向ofstream s的指针的容器时,代码编译为:

    #include <fstream>
    #include <vector>
    #include <cstdlib>
    #include <cstdio>
    int main()
    {
        // my container of ofstream(s)
        std::vector<std::ofstream*> fS;
        // instantiate an ofstream
        std::ofstream * of = new std::ofstream("myfile.txt");
        // push back to my container
        fS.push_back(of);
        return 0;
    }

为什么会这样?

当您在vector上调用push_back(of)时,它会尝试将对象of的副本添加到向量中。(c++喜欢复制东西)。在这种情况下,您试图复制ofstream,这是不允许的。直观地说,拥有一个ofstream的副本意味着什么并不清楚,所以规范禁止它。

另一方面,假设您有vectorofstream* s。现在,如果您尝试push_back指向ofstream的指针,那么c++将其解释为您应该将指针的副本放入vector中,这没关系,因为指针可以很容易地复制。

如果你有一个最新的编译器,还有第三个选择。c++最近引入了移动语义的思想,即与其尝试文件流复制到vector中,不如文件流移动到vector中。因此,您可以这样写:

int main()
{
    // my container of ofstream(s)
    std::vector<std::ofstream> fS;
    // instantiate an ofstream
    std::ofstream of("myfile.txt");
    // push back to my container
    fS.push_back(std::move(of));
    return 0;
}

这样做之后,变量of将不再引用原始文件流;它只会有一个虚拟值。但是,vector现在将有效地包含以前存储在of中的流。