如何阻止编译器删除我的函数

时间:2017-09-08 00:46:32

标签: c++ file

当我在重载return的末尾添加operator=语句时,编译器会抛出错误。它说:

  

' File :: File(const File&)'被隐式删除,因为默认定义是不正确的

但是,当我删除return语句(和类型说明符)时,没问题。

class File : public Document {
private:
    fstream mainFile;
    string drive, folder, fileName, fullPath;
protected:

public:
    File(string d, string f, string fn, string txt = "NULL") : Document(txt) {
        drive = d;
        folder = f;
        fileName = fn;
        if(fileName.find(".txt") == -1) {
            fileName.append(".txt");
        }
        fullPath = drive + ":/" + folder + "/" + fileName;
        mainFile.open(fullPath.c_str());
        mainFile << txt;
    }
    File() : Document() {
        drive = folder = fileName = "NULL";
        fullPath = drive + ":/" + folder + "/" + fileName;
    }

    File operator = (File & a) {
        this->getDrive() = a.getDrive();
        this->getFolder() = a.getFolder();
        this->getFileName() = a.getFileName();
        this->getText() = a.getText();
        this->fileName = a.fileName;
        return a;
    }

};

2 个答案:

答案 0 :(得分:4)

File operator = (File & a) {

此运算符按值返回其结果。也就是说,通过副本。

问题是File包含std::fstream成员,该成员本身有一个已删除的复制构造函数。它无法复制。 std::fstream表示可能打开的文件。 “复制”打开文件的概念完全没有意义,因此无法复制文件流对象,因此File本身无法复制,因为它包含一个不可复制的类成员,这就是原因编译错误。试图复制不可复制的类。

抛出return语句会导致一个未定义的行为,该行为被声明为返回File而不返回任何内容。

这完全是因为您实现赋值运算符的几个基本问​​题。赋值运算符应该:

  • 获取const参数。

  • 引用 返回给自己的实例,

  • 返回*this

为了实现具有预期语义的赋值运算符,它应该声明为

File &operator=(const File &a)

并通过返回

完成其工作
    return *this;

答案 1 :(得分:1)

您的复制操作员的签名应为:

File & operator=(File const &);

编译器抱怨return a;,因为运算符声明它返回一个对象而不是引用 - 因此需要复制a。但mainFilestd::fstream,它不提供自己的复制构造函数,因此编译器无法为您生成复制构造函数。您自己没有提供复制构造函数,因此File对象是不可复制的。这就是返回a时出错的原因。

正确的实施方式是:

File & operator=(File const & a) {
    this->getDrive() = a.getDrive();
    this->getFolder() = a.getFolder();
    this->getFileName() = a.getFileName();
    this->getText() = a.getText();
    this->fileName = a.fileName;
    return *this;
}

请注意,我们还通过const引用获取参数;这允许从File对象进行复制分配,这些对象是const(否则,你不能)。此外,赋值运算符通常应该返回对赋值目标的引用(*this,而不是a)。