【问题标题】:Why does 'const' behave differently in these two cases?为什么'const'在这两种情况下表现不同?
【发布时间】:2019-10-28 14:13:01
【问题描述】:

我有一个问题,为什么在“一步”完成时可以编译某件事,但在“两步”完成时不能编译。我有三个班级;

class Time {
  int mTime;

  int Time::getTimeAsUnix() const {return mTime;}
}

class Travel {
  Time mTimestamp;

  const Time& Travel::getTime() const { return mTimestamp; }
  Time& Travel::getTime() { return mTimestamp; }
}

class Analysis : public Travel {

  int Analysis::getUnixTime() const {
    // Time& t = Travel::getTime();
    // return t.getTimeAsUnix();     // This does NOT compile

    return Travel::getTime().getTimeAsUnix();  // This compiles
  }
}

任何人都知道为什么在 Analysis 类中,非注释方法编译,而注释方法给我一个即时 “c++ 错误:将 'const Time' 绑定到类型 'Time&' 的引用丢弃限定符” em> 我什么时候试试?

执行时这两者不完全一样吗??

【问题讨论】:

  • 你试过const Time& t = Travel::getTime();吗?
  • 我很确定没有编译的行是Time& t = Travel::getTime();,因为你所在的方法本身就是 const 并且会拒绝调用非常量方法。总之,这不是因为你分两步做,而是因为你显式调用了非常量方法。

标签: c++ reference constants qualifiers


【解决方案1】:

线

Time& t = Travel::getTime();

需要

const Time& t = Travel::getTime();

让它工作。需要这样做的原因是因为你在一个 const 限定的函数中。当您在一个 const 限定函数中时,该类的所有成员都被认为是 const。这意味着当您致电getTime 时,您会致电

const Time& Travel::getTime() const { return mTimestamp; }

函数的版本。尝试将 const Time& 分配给 Time& 是行不通的,因为您将剥离返回类型的常量。

【讨论】:

    【解决方案2】:

    在这个函数定义中你应该删除Analysis::

      int Analysis::getUnixTime() const {
         Time& t = Travel::getTime();
         return t.getTimeAsUnix();  
      }
    

    有调用函数

    const Time& Travel::getTime() const { return mTimestamp; }
    

    返回一个常量引用。之所以使用这个重载函数,是因为函数getUnixTime声明为一个const成员函数。

    然而常量引用被分配给非常量引用

         Time& t = Travel::getTime();
    

    所以编译器发出错误。

    【讨论】:

      【解决方案3】:

      好的,让我们分解一下工作版本:

      int Analysis::getUnixTime() const { // (1)
          // (2) --------v        v----- (3)
          return Travel::getTime().getTimeAsUnix();
      }
      

      (1),函数getUnixTime 被定义为在常量实例上工作。这意味着您只能调用其他常量函数,而不能更改任何成员变量。

      (2)Travel::getTime() 被调用。这调用了一个非静态成员函数,尽管它的语法。不过没关系,很清楚,调用const版本的函数,返回const Time&。对常量 Time 对象的引用。

      (3),成员函数getTimeAsUnixconst Time& 上被调用。这是完美的,因为Time 有一个以这种方式命名的成员函数,它被标记为在常量对象上工作。

      如你所见,每个对象都是常量,你只调用常量函数。


      将代码分成两行时出了什么问题?

      让我们看一下函数体中的第一行:

      Time& t = Travel::getTime();
      

      正如我们所说,Travel::getTime() 调用一个非静态成员函数。因为this 是一个常量对象(你在一个常量函数中),所以getTime 的常量版本被调用,就像以前一样。

      const getTime 的返回类型是const Time&

      然后你做Time& t =。这就是你的错误所在。 const Time& 无法修改。可以修改Time&。如果您使用可变引用来引用常量对象,那么您将能够改变常量对象。语言禁止这样做!

      要解决这个问题,只需使用常量引用:

      const Time& t = Travel::getTime();
      

      【讨论】:

        猜你喜欢
        • 2020-03-13
        • 2019-11-08
        • 1970-01-01
        • 2017-04-25
        • 2015-11-27
        • 1970-01-01
        • 2017-09-22
        • 1970-01-01
        相关资源
        最近更新 更多