如何处理const对象中非const引用成员的初始化? [英] How to deal with initialization of non-const reference member in const object?

查看:184
本文介绍了如何处理const对象中非const引用成员的初始化?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们假设您有一个类

    class C 
    {
      int * i;

      public:

         C(int * v):i(v) {};

         void method() const;  //this method does not change i
         void method();        //this method changes i
    }

现在你可能要定义这个class

Now you may want to define const instance of this class

    const int * k = whatever;
    const C c1(k); //this will fail

但是这将失败,因为非const int C的构造函数C v)

but this will fail because of non-const int C's constructor C(int * v)

所以你定义一个const int构造函数

so you define a const int constructor

    C(const int * v):i(v) {}; //this will fail also

但是这也会失败,因为C的成员int * i -const。

But this will fail also since C's member "int * i" is non-const.

在这种情况下该怎么办?使用mutable?铸件?准备const类的类?

What to do in such cases? Use mutable? Casting? Prepare const version of class?

编辑:与Pavel讨论后(下)我调查了这个问题一点。对我来说,C ++是不正确的。指针目标应该是严格类型,这意味着你不能例如做以下:

edit: After discussion with Pavel (below) I investigated this problem a bit. To me what C++ does is not correct. Pointer target should be a strict type, that means that you could not for example do the following:

int i;
const int * ptr;
ptr = & i;

在这种情况下,语言语法将 const 承诺不改变指针的目标。另外 int * const ptr 是一个不改变指针值的承诺。因此,你有两个地方可以应用const。然后你可能想要你的类模型一个指针(为什么不)。而这里的事情正在崩溃。 C ++语法提供了const方法,它们能够承诺不改变字段的值本身,但没有语法指出你的方法不会改变你的类指针的目标。

In this case language grammar treats const as a promise not to change pointer's target. In addition int * const ptr is a promise not to change pointer value itself. Thus you have two places where const can be applied. Then you may want your class to model a pointer (why not). And here things are falling into pieces. C++ grammar provides const methods which are able to promise not to change field's values itself but there is no grammar to point out that your method will not change targets of your in-class pointers.

一个解决方法是定义两个类 const_C C 例如。这不是一个皇家路。有了模板,他们的部分专业化很难不陷入混乱。还有所有可能的参数变量,如 const const_C& arg const C& arg const_C& arg C& arg 看起来不漂亮。我真的不知道该怎么办。使用单独的类或const_casts,每种方式似乎是错误的。

A workaround is to define two classes const_C and C for example. It isn't a royal road however. With templates, their partial specializations it's hard not to stuck into a mess. Also all possible arguments variations like const const_C & arg, const C & arg, const_C & arg, C & arg don't look pretty. I really don't know what to do. Use separate classes or const_casts, each way seems to be wrong.

在这两种情况下,我应该标记不修改指针的目标为const的方法?或者只是遵循const方法不改变对象的状态本身的传统路径(const方法不关心指针目标)。然后在我的case所有的方法将是const,因为类是建模一个指针,因此指针本身是 T * const

In both cases should I mark methods which don't modify pointer's target as const? Or just follow traditional path that const method doesn't change object's state itself (const method don't care about pointer target). Then in my case all methods would be const, because class is modelling a pointer thus pointer itself is T * const. But clearly some of them modify pointer's target and others do not.

推荐答案

您的示例不会失败, k 按值传递。成员 i 是'隐式常量',因为当实例不变时,不能更改 C 的直接成员。

Constness说在初始化之后不能更改成员,但是初始化列表中的值初始化当然是允许的 - 你还能给他们一个值吗?

Your example doesn't fail, k is passed by value. The member i is 'implicitly constant' as direct members of C can't be changed when the instance is constant.
Constness says that you can't change members after initialization, but initializing them with values in the initialization list is of course allowed - how else would you give them a value?

不起作用是调用构造函数而不公开它);

What doesn't work is invoking the constructor without making it public though ;)

更新寻址更新的问题:

是的,C ++有时会强制您进入某种繁琐状态,但 const正确性是一种常见的标准行为,您不能仅仅重新定义, 。 Pavels answer 已经解释了一个常见的习惯用法,用于经验证的库,如STL,用于解决这种情况。

Yes, C++ forces you into some verboseness sometimes, but const correctness is a common standard behaviour that you can't just redefine without breaking expectations. Pavels answer already explains one common idiom, which is used in proven libraries like the STL, for working around this situation.

有时你必须接受语言有限制,仍然处理接口用户的期望,即使这意味着应用一个明显的次优解决方案。

Sometimes you have to just accept that languages have limitations and still deal with the expectations of the users of the interface, even if that means applying an apparently sub-optimal solution.

这篇关于如何处理const对象中非const引用成员的初始化?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆