【问题标题】:How const member function can change an object's data?const 成员函数如何更改对象的数据?
【发布时间】:2014-01-17 02:34:07
【问题描述】:

还有一个关于 C++ 中 const 关键字用法的问题(我是 C++ 新手,试图在 SO 上找到答案 - 答案太多但找不到答案)。
问题1:在下面的成员函数中

template <class T>  
bool BinTree<T>::insert( Node<T>* & node, const T& val ) const  
{
    node = new Node<T>(val);
}

我能够更改作为参考传递的类数据。 const 的成员函数怎么样?这个const 是否仅阻止数据显式更改,但允许通过引用进行更改?
2. 能否确认一下我的理解:

func( const Node<T>* const & node ) {...}

在这个函数签名中,第 2 个 const 表示 const 指针,第 1 个 const 表示 const Node(因此该节点是对 const 指针的引用,指向 const Node)?

【问题讨论】:

  • 第二次由下面的@tabstop 确认。第一个呢?我没有发布整个代码,因为它很明显:有一个对象的字段作为引用传递给 const 成员并在那里更改!
  • parashift.com/c++-faq/const-member-fns.html
  • "(所以该节点是对 const 指向 const 节点的指针的引用)" 是的,但是引用方面不太可能产生任何有用的影响,因为传递对 const pointer 的引用可能需要与按值传递 const 指针相同的寄存器/堆栈字节数。
  • 你在 cmets 中说你在调用“insert”时将指向根节点的指针作为“node”参数传递:你似乎没有在“封装”或“const”...您通常希望将数据插入树中,其中只有树对象本身需要关心哪个节点是根,即节点是“私有”数据成员。 insert 函数应该是非常量的,因此它可以修改 root。照原样,您的函数可能是static 而不是const,因为它不会根据对对象实例的隐式访问(即通过this)修改任何内容。
  • @Tony D 同意。正如我在 cmets 中所说,我在玩 const 成员并期待一个错误。令我惊讶的是,在这种情况下没有错误。下面的 cmets 似乎可以解释这一点。

标签: c++ constants


【解决方案1】:

成员函数是 const 意味着,就函数而言,this 对象(BinTree&lt;T&gt;)是 const。 (当然val 是 const,因为它被标记了。)(编辑:这有点令人惊讶,因为insert 听起来不像你对const 树所做的那种功能,因为你会'不能更新任何内部数据结构。)

您的函数签名是正确的——第一个表示“指向的东西”是 const,第二个表示指针本身是 const。


根据 cmets 中的进一步讨论进行编辑: 该函数将this 对象视为常量,将node 视为非常量。因此,您不能直接更改任何成员变量。 但是,如果 node 恰好是对 this 成员的引用(假设它是通过调用的

foo.insert(foo.root);

那么那个特定的成员变量是可以改变的,但是只能通过node的别名。编译器甚至不会注意到 thisnode 这两个对象是相关的,因为在它查看函数 insert 时它们并不相关(只有当调用实际发生时才会发生别名)。 const 仅适用于(文字,如果隐含)this;任何其他的指针或引用都可以做他们想做的事。

【讨论】:

  • 您对insert 函数的看法是正确的,我只是在玩,以为我会在 const 成员中收到node = ... 的错误。所以我的第一个问题为什么它有效? const 成员函数更改了this 的数据。
  • 我不知道您所说的“更改了this 的数据”是什么意思。您更改了node,这是传入的参数。您根本没有更改this 对象中的任何内容。
  • 这就是重点:我将根作为node 传递并更改了它的值。我错过了什么?编辑:为避免误解,我有一个 BinTree 对象,它有一个私有字段 root 我将根传递给 const 成员函数作为参考,并成功更改了 root 值。
  • @TT_ 如果您当时在问题中添加了该方面,将会有所帮助。但本质上 const 仅适用于编译器在该函数的上下文中可以看到的内容。它不知道 node 参数来自哪里(毕竟它可能完全是某个其他对象的 Node),因此函数级 const 不适用于它。
  • parashift.com/c++-faq/const-member-fns.html 似乎证实了你在说什么(我怀疑我的问题:“......这个 const 只阻止数据显式更改,但允许通过引用更改它”)。
猜你喜欢
  • 2021-05-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-01-08
  • 1970-01-01
  • 2013-06-07
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多