我在类中有一个成员变量,其类型为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;
}
答案 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 ++以这种方式行事的任何正当理由。