C++ 为什么我的 fstream 被隐式删除?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/12432952/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 16:16:05  来源:igfitidea点击:

Why is my fstream being implicitly deleted?

c++classinheritancefstream

提问by Andy E

I'm working with a few HID devices, all of which have classes deriving from the following base class (in main.h):

我正在使用一些 HID 设备,所有这些设备都有派生自以下基类(在main.h 中)的类:

class HIDDevice {
    public:
        hid_device *device;

        virtual void read(std::fstream)=0;
        virtual void write(std::fstream)=0;
};

Here's one of the device classes deriving from it (device.h):

这是从它派生的设备类之一(device.h):

class MyDevice : public HIDDevice {
    public:
        void read(std::fstream);
        void write(std::fstream);
};

...and a sample of the implementation:

...以及实现示例:

void MyDevice::read(std::fstream file) {
    // Read from card and write to file
    response = send_command(READ_DEVICE);
    file.write((char *)&response[0], response.size());
}

...and the caller:

...和来电者:

fstream file (filename, ios::binary | ios::in);
dev->read(file);

When I try and compile, I get the following error:

当我尝试编译时,出现以下错误:

main.cpp:294:27: error: use of deleted function ‘std::basic_fstream::basic_fstream(const std::basic_fstream&)'
In file included from source/main.cpp:24:0: /usr/include/c++/4.6/fstream:761:11: error: ‘std::basic_fstream::basic_fstream(const std::basic_fstream&)' is implicitly deleted because the default definition would be ill-formed:

main.cpp:294:27: 错误:使用已删除的函数 'std::basic_fstream::basic_fstream(const std::basic_fstream&)'
在 source/main.cpp 包含的文件中:24:0: /usr/include/c++ /4.6/fstream:761:11: 错误:'std::basic_fstream::basic_fstream(const std::basic_fstream&)' 被隐式删除,因为默认定义格式错误:

... and I have no idea why, probably because I'm fairly new to C++ and I've done something idiotic.

...我不知道为什么,可能是因为我对 C++ 还很陌生,而且我做了一些愚蠢的事情。

Changing the arguments back to references (using &), I get the following error:

将参数改回引用(使用 &),我收到以下错误:

/main.o:(.rodata._ZTV13MyDevice[vtable for MyDevice]+0x18): undefined reference to `MyDevice::write(std::basic_fstream >&)'

/main.o:(.rodata._ZTV13MyDevice[vtable for MyDevice]+0x18):对`MyDevice::write(std::basic_fstream >&)'的未定义引用

Can anyone help me fix this problem?

谁能帮我解决这个问题?

回答by WhozCraig

Try tossing those std::fstreams around by reference.

尝试std::fstream通过参考扔掉那些s 。

class MyDevice : public HIDDevice {
    public:
        void read(std::fstream&);
        void write(std::fstream&);
};

回答by Aaron Burghardt

Just for reference, I had the same compiler error, but created it in a different way that wasn't immediately obvious to me. Out of habit I wrote:

仅供参考,我有相同的编译器错误,但以不同的方式创建它,这对我来说并不是很明显。出于习惯,我写道:

auto stream = fstream(output, iOS::out | iOS::binary);

Which, of course, creates a temporary fstream object and copies it to stream. That worked in Xcode 6 using clang, but not for GCC 4.9.2.

当然,这会创建一个临时 fstream 对象并将其复制到流。这在 Xcode 6 中使用 clang 有效,但不适用于 GCC 4.9.2。

回答by Jon

The HIDDevicemethod signatures mean that the fstreams are being passed around by value. This in turn means that copies of the original stream objects have to be created at the call site using the copy constructor. It is this copy constructor that has the canonical signature std::basic_fstream::basic_fstream(const std::basic_fstream&).

HIDDevice方法签名意味着fstreams的按值传递左右。这反过来意味着必须使用复制构造函数在调用站点创建原始流对象的副本。正是这个具有规范签名的复制构造函数std::basic_fstream::basic_fstream(const std::basic_fstream&)

The compiler is telling you that for some reason (which has to do with the particulars of the basic_fstreamimplementation your standard library uses) it cannot auto-generate this copy constructor, hence it cannot fulfill your implicit command to make copies of the streams.

编译器告诉您,由于某种原因(这与basic_fstream您的标准库使用的实现的细节有关),它无法自动生成此复制构造函数,因此它无法执行您创建流副本的隐式命令。

As others have already said, the usual modus operandi (which will also prevent the error here) is to pass the arguments by reference instead of by value.

正如其他人已经说过的那样,通常的操作方式(这也将防止此处出现错误)是通过引用而不是通过值传递参数。

回答by Jonathan Seng

&std::fstreamas a parameter will pass it around by reference to be used as the same object everywhere. This avoids the implementation trying to create another instance and then closing the stream when the functions end (because the copied object is being destructed).

&std::fstream作为参数将通过引用传递它以在任何地方用作相同的对象。这避免了实现尝试创建另一个实例然后在函数结束时关闭流(因为复制的对象正在被破坏)。

Make sure you change this in both the declaration and the implementation of the member function (i.e. in the class and where the body is).

确保在成员函数的声明和实现中(即在类中和主体所在的位置)中更改此设置。