ReadingLab / Discussion-for-Cpp

C++ 中文讨论区
MIT License
88 stars 63 forks source link

const和返回*this的问题 #5

Closed csbdong closed 9 years ago

csbdong commented 9 years ago

7.1.2节谈到了引入const成员函数的作用,7.3.2节又提到了*从const成员函数返回this**,有点混淆了,下面举个例子(在类中与本问题无关的部分都被省略)

class Screen
{
public:
    Screen set2() const
    {
        return *this;
    }

    Screen& set5()const
    {
        return *this;
    }
};

很显然,有些是错误的。 this类型默认情况下是指向类类型的非常量版本的常量指针

问题在这里:

头文件中的set5()已经报错。 我的理解:因为是this类型是const Screen *const,但是返回值类型只是Screen类型的引用(非常量类型),所以报错??? 但是,为什么在set2() 中就没有报这个错呢??两个成员函数的区别只是返回值一个是引用但是一个不是?

pezy commented 9 years ago

你加了 const 修饰成员函数,那么也就默认是由 const 对象 来调用它了。

那么逻辑上自然就不会允许在这个成员函数里对该对象进行修改

Mooophy commented 9 years ago

@csbdong 欢迎参与讨论,我编辑了一下你的提问,去掉了不相关的部分。请参考一下。

Mooophy commented 9 years ago

认同 @pezy

csbdong commented 9 years ago

@pezy 还有些我没表述清楚。 1.你的解释:你加了 const 修饰成员函数,那么也就默认是由 const 对象 来调用它了。 对于set2()。调用它的是个const类型的对象,执行合法,返回的是个副本(这个副本难道不是也应该是const类型的吗?这样不就与成员函数的返回值不符了?) 2.set5() 返回引用,意味着可以修改对象,如 c.set5().change(). (不合法) 那么为什么const Screen& set5()const;合法?

pezy commented 9 years ago

这个const 不是用来修饰this的吗?默认是由 const 对象调用?

this 不就是调用它的对象吗 (c),const 修饰调用方,所以是由 const 对象调用呀。

为什么const Screen& set5()const;合法了呢???

const 对象调用,返回 const 引用对象,逻辑上自洽啊。

这个副本难道不是也应该是const类型的吗?这样不就与成员函数的返回值不符了?

为什么副本是 const 的?set2() 的返回值分明是 Screen 啊,又不是 const Screen.

那么为什么const Screen& set5()const;合法?

上面已经解释了。

csbdong commented 9 years ago

@pezy
我来说下为什么我理解的set2()返回值副本是const类型

int main()
{
const Screen s;
s.set2();
}

s.set2() 调用合法,但是这时候this就是调用它的对象(s),返回的是s的副本,s是const Screen类型,但是函数的返回值是Screen。

pezy commented 9 years ago

返回的是s的副本,s是const Screen类型

我琢磨了半天你的话,想问下,你是不是认为 copy 会连 const 属性也 copy 过去?即 const Screen 的副本也应该是 const 的?

csbdong commented 9 years ago

@pezy 对,我是这么认为的,但是不知道事实是不是?所以才产生上面的疑问。

pezy commented 9 years ago

但是不知道事实是不是?

显然不是。学 C++ 切记不要想当然。对象的 Copy 操作,会在第 13 章讲,等你学到那里,就清晰了。

csbdong commented 9 years ago

好的,明白。