鱼C论坛

 找回密码
 立即注册
查看: 1528|回复: 3

[已解决]关于const修饰符的问题,难道使用const就一定会这么纠结么

[复制链接]
发表于 2018-12-13 20:21:17 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
最近在尝试自己实现一些数据结构。为了小甲鱼说的养成良好的习惯嘛,试着在能加上const修饰符的地方尽量加上,但是发现了一些const在继承上的很纠结的问题。
比如说这样一个程序:
class Obj
{
public:
        int value;
};

class A
{
private:
        Obj t;

        Obj &func1()
        {
                Obj *p = &t;
                //如果这是某个复杂的实现,有其他函数也需要使用,所以不能加const修饰自身
                return *p;
        }
public:
        const int func1_value() const //会报错,因为这个函数的this指针类型为const A而A::func1()的this指针类型是A&
        {
                return func1().value;
        }

        bool set_func1_value(int i)
        {
                func1().value = i;
        }
};

作为强迫症,总是想在func_value()后面加上const..但是这样一定会报错。。如果我一定想要实现每一个不做具体改动public函数都有const修饰的话,难道需要再写一个完全一样只是使用了const修饰的func1么,有什么其他的办法么
最佳答案
2018-12-14 18:04:44
class Obj
{
public:
        int value;
};

class A
{
public:
        Obj t;

        Obj &func()
        {
                const Obj &p = static_cast<const A &>(*this).func();
                return const_cast<Obj &>(p);
        }

        const Obj &func() const
        {
                const Obj *p = &t;
                // ...
                return *p;
        }

        const int func1_value() const
        {
                return func().value;
        }

        bool set_func1_value(int i)
        {
                func().value = i;
        }
};
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2018-12-13 22:11:27 | 显示全部楼层
Obj &func1()
        {
                Obj *p = &t;
                //如果这是某个复杂的实现,有其他函数也需要使用,所以不能加const修饰自身
                return *p;
        }
const int func1_value() const //会报错,因为这个函数的this指针类型为const A而A::func1()的this指针类型是A&
        {
                return func1().value;
        }

func1_value是const的,也就是func1_value保证自己不修改当前对象,这也就意味着func1_value函数只能调用 保证不修改当前对象的函数(const函数),func1没有做这样的保证,所以func1_value函数不能调用func1
修改的确是在func1内部进行的,但是func1_value调用了func1,可以认为是func1_value间接修改了当前对象,间接修改也还是修改,func1_value保证自己不修改当前对象,所以func1_value函数不能调用func1
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-12-13 23:17:08 | 显示全部楼层
本帖最后由 Croper 于 2018-12-13 23:20 编辑

我大概知道是这么回事
现在的问题是func_1的实现如果需要写很长一段代码,返回的是Obj的一个实例,但是func_1的函数内部并没有显式地修改当前对象
之所以func_1不加const的原因是的原因是其他调用func_1的函数可能会修改这个实例。
比如在这个例子中set_func1_value也调用了func_1的返回值
        bool set_func1_value(int i)
        {
                func1().value = i;
        }
如果把func_1改成const的那么set_func1_value又会报错

我知道如果改成这样,是能达到我想要的效果的
class A
{
public:
        Obj t;

        Obj &func1()
        {
                Obj *p = &t;
                //如果这是某个复杂的实现,返回的值可能是t,有其他函数也需要使用,所以不能加const修饰自身
                return *p;
        }

        const Obj &func1_const() const //新建一个函数func1_const,和func_1完全一样,仅仅是比func1多了几个个const
        {
                const Obj *p = &t;
                //这里是和func1完全相同的代码,一点都不变,
                return *p;
        }
        
        const int func1_value() const
        {
                return func1_const().value;       //改成调用func1_const的返回值
        }

        bool set_func1_value(int i)
        {
                func1().value = i;
        }
};

但是这样显得好蠢,同样的代码谢了两次。。维护也麻烦啊。就不能有什么办法使得代码能够复用,让const int func1_value在调用func_1的同时保证自身的const么
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2018-12-14 18:04:44 | 显示全部楼层    本楼为最佳答案   
class Obj
{
public:
        int value;
};

class A
{
public:
        Obj t;

        Obj &func()
        {
                const Obj &p = static_cast<const A &>(*this).func();
                return const_cast<Obj &>(p);
        }

        const Obj &func() const
        {
                const Obj *p = &t;
                // ...
                return *p;
        }

        const int func1_value() const
        {
                return func().value;
        }

        bool set_func1_value(int i)
        {
                func().value = i;
        }
};
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-10-3 00:26

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表