为什么'const'在这两种情况下的行为不同?



我有一个问题,为什么某件事可以"一步完成"编译,但不能"两步完成"。我有三节课;

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&'类型的引用会丢弃限定符">

执行死刑时这两件事不是完全一样吗??

Time& t = Travel::getTime();

需要

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

让它发挥作用。之所以需要这样做,是因为您在一个const限定的函数中。当您在const限定函数中时,类的所有成员都被认为是const。这意味着当你呼叫getTime时,你就呼叫

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

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

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

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

称为函数

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

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

然而,常数参考被分配给非常数参考

Time& t = Travel::getTime();

因此编译器会发出错误。

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

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的常量版本会被调用,就像以前一样。

常量getTime的返回类型为const Time&

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

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

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

相关内容

最新更新