【问题标题】:Why the const keyword is disqualified if I return an object of the const definition?如果我返回 const 定义的对象,为什么 const 关键字不合格?
【发布时间】:2017-09-08 02:34:15
【问题描述】:

这些 sn-ps 的代码非常短,但我无法理解 const 关键字缺少什么。在我的第一个 sn-p 中,当我将 const 放在函数定义之后时,它表示仅返回某些内容会使 const 关键字不合格:

string & getText() const {
    return txt;
}

jdoodle.cpp:在成员函数'std::__cxx11::string& Document::getText() const'中: jdoodle.cpp:29:16: 错误:绑定'const string {aka const std::__cxx11::basic_string}' 到类型'std::__cxx11::string& {aka std::__cxx11::basic_string&}' 的引用丢弃限定词 返回.txt; ^

第二个,当我简单地把 return a;而不是返回 *this;我最终违反了 const 关键字。

File & operator = (const File & a) {
    this->drive = a.drive;
    this->folder = a.folder;
    this->fileName = a.fileName;
    this->txt = a.txt;
    this->fullPath = a.fullPath;
    return a;
}

jdoodle.cpp:在成员函数'File& File::operator=(const File&)'中: jdoodle.cpp:117:16:错误:将“const File”绑定到“File&”类型的引用丢弃限定符 返回一个; ^

最后,第三个(当我像现在这样放入实际的修改器时,它会引发违规错误——与我只放入成员变量时不同):

File & 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;
}

【问题讨论】:

  • 它被称为const-correctness。您不能隐式地从 const 转到非 const。

标签: c++ constants


【解决方案1】:

作为赋值运算符时,you probably want to return *this

话虽如此,您仍然收到有关您的 getter 函数丢弃限定符的错误。

即使我建议您在赋值运算符中直接使用成员,您也可以通过以下方式修复代码。

您的 getter 函数可能如下所示:

string& getText() {
    return txt;
}

您需要为 const 对象提供一个额外的重载:

const string& getText() const {
    return txt;
}

这里的区别在于this,并且每个成员都是const 在一个const 限定函数中。由于您要返回对该字符串的引用,它更 const,因此您需要返回一个 const 引用。

通过提供 const 和非 const 版本,您仍然可以改变 getter 返回的对象,并且额外的重载将使非可变 getter 与非可变对象一起工作。

【讨论】:

  • 所以我尝试这样做,它运行没有错误。但是,为了测试修改的 R/L 值兼容性,我运行了 Document b; b.getText() = a.getText()。我得到了丢弃 const 限定符的相同错误。
  • @RaymondIacobacci 在实践中,用 getter 分配有点破坏了 getter 的意义。如果你需要提供访问器,你也应该提供设置器。此外,您似乎没有超载该功能。如果您想通过 getter 进行分配,您应该提供 const 版本非 const 版本。
  • 好的。所以应该不需要 L-Value/可能的 getter,因为那将是一个 setter。
  • @RaymondIacobacci 好吧,有时这是必要的。有些类不需要封装,在某些情况下返回可变引用可以使事情变得更容易。如果您需要封装,我建议仅使用 const getter 并提供 setter,但前提是绝对需要。但是,当我不需要封装时,我倾向于完全跳过访问器并公开暴露成员。
猜你喜欢
  • 2020-04-15
  • 2019-05-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-10-31
  • 2019-06-26
  • 2021-12-09
相关资源
最近更新 更多