ofstream in class - 尝试引用已删除的函数

时间:2014-12-15 19:48:19

标签: c++ string parameters char fstream

我在类中有一个成员变量,其类型为ofstream,构造函数包含字符串参数:

class dogs
{
public:
    ofstream dogsFile;

    dogs(string location)
    {

    }
};

出现以下错误:

  

错误2错误C2280:'std :: basic_ofstream> :: basic_ofstream(const std :: basic_ofstream>&)':尝试引用已删除的函数c:\ users \ pc \ documents \ visual studio 2013 \ projects \ database \ database \ database.cpp 26 1数据库

我再次尝试了这段代码,但我没有使用字符串,而是使用了char *:

class dogs
{
public:
    ofstream dogsFile;

    dogs(char* location)
    {

    }
};

错误消失了。为什么?为什么字符串会出错?

编辑: 这是整个代码:

#include "stdafx.h"
#include <iostream>
#include <fstream>
#include <string>

using namespace std;


class dogs
{ 
    ofstream dogsFile;

public:
    dogs(string location)
    {

    }
};

int main(int argc, _TCHAR* argv[])
{
    dogs dog = dogs("dog.bin");
    return 1;
}

2 个答案:

答案 0 :(得分:2)

Dieter的原始答案似乎是正确的。 即这将编译:

dogs *dog = new dogs("dog.bin");

你的专栏不会,请参阅他关于复制构造函数的答案。

狗(&#34; dog.bin&#34;)将创建一个对象然后&#34; =&#34;将制作它的副本并将其交给狗。无法复制带有ofstream的对象。

您也可以使用

解决此问题
dogs dog("dog.bin");

代替。

答案 1 :(得分:0)

我无法将此视为VC ++中的错误。

定义dogs类的方式,编译器应该为它生成一个隐式移动构造函数,它将调用std::ofstream的移动构造函数,即defined as of C++11

何时定义隐式移动构造函数的规则在[12.8 / 9]和[12.8 / 11]的标准中指定。他们还列出了here。在这种情况下,我无法看到任何理由不声明隐式移动构造函数。

然后,行

dogs dog = dogs("dog.bin");

必须调用从右侧的临时dogs对象到左侧dog的移动(移动可能被省略,但构造函数仍需要可访问)。

简而言之,一切都应该正常。

它在Clang 3.5中有用。它在GCC中不起作用,但仅仅因为它没有为流类定义移动构造函数(在这方面它不符合标准)。

有趣的是,如果dogs构造函数被声明为除了std::string之外的其他任何东西,它就可以在VC ++中工作,正如OP所提到的那样。将构造函数更改为以下任何一个:

dogs(const string& location)

dogs(int a) //And change the call accordingly, of course.

dogs(A a) //And change the call accordingly (A is a user-defined class).

并且VC ++中的一切都能正常工作。

它不仅仅适用于通过值传递的std::string这一事实似乎表明编译器中存在错误。基本上,在这种情况下,只有在这种情况下,编译器决定不定义隐式移动构造函数,这会导致复制初始化回退到调用复制构造函数,从而导致错误。

如果你明确定义了移动构造函数,就像这样:

dogs(dogs&& arg) : dogsFile(std::move(arg.dogsFile)) { }

再次,一切正常,包括构造函数按值std::string

我无法看到VC ++以这种方式行事的任何正当理由。