请澄清 const 限定符传播

Posted

技术标签:

【中文标题】请澄清 const 限定符传播【英文标题】:Please clarify const qualifier propagation 【发布时间】:2016-05-18 09:35:12 【问题描述】:

假设我们有以下一段代码:

class Base 
  public:
    int a = 5;
;

class Derived : public Base 
  public:
    Base *parent_ = new Base;
    Base* parent() const  return parent_; 
;

void f(const Derived *derived) 
    Base *p = derived->parent();
    p->a = 10; // <- is this correct?

我个人认为这是一个问题:

在函数f 中,我们获取一个指向constDerived 对象的指针。这使得它的每个成员也是const,因此parent_ 变为const Base *。如果它是 const,我们不应该有能力修改指针指向的对象。

我哪里错了?

【问题讨论】:

parent_ 的类型是 Base * const,而不是 const Base * @sashoalm yes. 顺便说一句,问题并不是真正特定于继承。恕我直言,最好编辑和删除任何继承的东西 好吧,您的代码中有继承,但问题不是由此引起的。答案甚至没有提到继承。恕我直言,更好的标题是“返回指针时澄清 const 限定符” @VictorPolevoy : tobi303 指的是 Derived 在您的代码示例中继承自 Base - 这对您的问题没有影响,实际上可能会导致一些混淆 Base 的使用作为基类和成员。 【参考方案1】:

这使得它的每个成员也是 const 从而parent_ 变为const Base *

不,指针将变为 const 本身,而不是它指向的对象。所以parent_变成Base * const,而不是const Base *,你的代码是有效的。

【讨论】:

【参考方案2】:
Base* parent() const  return parent_; 

不幸的是,这是 C++ 的问题。方法是const,但它返回一个非常量指针,这将允许以下操作成功:

p->a = 10; // <- is this correct?

程序员有责任不从函数返回非常量指针或引用(方法是否为 const)。

【讨论】:

根据@songyuanyao 的回答,这不是问题,因为我们更改了保留为non-const 的对象,因为唯一由const propagation 变为const 的是指针本身。跨度> @VictorPolevoy 我会说这是个问题。你没有打破语言,但你打破了逻辑的不变性。【参考方案3】:

正如 tobi303 在下面指出的,这个答案是错误的。为了下面的讨论,将其保留在这里。


我可能是错的,但是这一行:

    Base* parent() const  return parent_; 

没有提到任何关于返回 const 对象的内容。相当于

    Base* parent() const  return this->parent_; 

其中thisconst Derived*,但parent_ 仍然是Base*

【讨论】:

const 对象的成员也是const,否则整个const 故事对于公共成员来说毫无用处 @tobi303 你好像不明白const T *T * const的区别 thisconst Derived* constparent_Base* const @M.M 我明白其中的区别。但正如宋元耀所指出的,如果thisconst,那么它的成员parent_也是const。由于该成员是一个指针,因此作为const 对象的成员,它成为const 指针(指向一个非常量对象)。实际上,我无意将此答案称为“错误”.... @tobi303,我真的很感谢你纠正了我。也许应该将当前讨论的简明版本编辑为已接受的答案。【参考方案4】:

const 方法仅防止该方法修改类的任何非可变数据成员。

如果你不想让a的修改,又不想更新类,你需要写:

const Base *p = derived->parent();

但是,我建议您不要将类中的非常量数据成员作为 ref 或指针返回,因为这破坏了 C++ 的数据封装概念。当然,公众号a也是如此。

【讨论】:

以上是关于请澄清 const 限定符传播的主要内容,如果未能解决你的问题,请参考以下文章

const限定符

C++杂谈const限定符与const指针

const限定符用法汇总

const 不兼容的类型限定符问题

精通C语言ANSI C 类型限定符const,volatile,restrict,_Atomic

精通C语言ANSI C 类型限定符const,volatile,restrict,_Atomic