【问题标题】:Const function eventually modifies itself through friend class [duplicate]const函数最终通过朋友类修改自己[重复]
【发布时间】:2014-05-26 02:41:11
【问题描述】:

在我的实现中,我有一个主类Tree,其中包含许多Nodes。每个Node 都包含一个指向下一个Node 的指针,如果没有实现它可以为NULL。 Tree 跟踪节点总数。

通过Tree 实现了一个搜索功能,该功能返回Node 指针。但是,如果 Node 尚不存在,则会创建一个新节点。这会增加 Tree::m_totalnodes 变量。但是,Tree::GetNode 是 const,但此修改不提供任何警告、错误或运行时故障。这是什么原因(可能与tbNode::m_tree 是非常量有关)?

class Node;             //forward declare

class Tree {
public:
    Tree() : m_totalnodes(0) {
        m_firstnode =  new Node(this,0);
    }
    Node* GetNode(int nodenumber) const {           //note const! Should not modify Tree
        return m_firstnode->FindNode(nodenumber);   //this function eventually modifies it (and no warning)
    }
private:
    friend class Node;
    unsigned int m_totalnodes;
    Node* m_firstnode;
};

class Node {
public:
    Node(Tree *thetree, int nodenumber) : m_tree(thetree),  m_nextnode(NULL), m_nodenumber(nodenumber) {
        m_tree->m_totalnodes++;
    }
    Node* FindNode(int nodenumber) {
        if (!m_nextnode)
            m_nextnode =  new Node(m_tree, nodenumber);
        return m_nextnode;
    }
private:
    Tree* m_tree;
    Node* m_nextnode;
    unsigned int m_nodenumber;
};

【问题讨论】:

    标签: c++ tree constants


    【解决方案1】:
    Node* m_firstnode;
    

    当您调用 const 之类的 GetNode 方法时,this 变为 const-qualified 类型 Tree const *。当您访问像 m_totalnodes 这样的成员时,他们似乎是像 unsigned int const 这样的 const-qualified。您不能修改对象。 m_firstnode 变为Node * const:不能修改指针,但仍然可以修改它指向的Node

    如果要全面避免误修改,通过重载的getter函数访问m_firstnode

    Node * & firstnode() { return m_firstnode; }
    Node const * firstnode() const { return m_firstnode; }
    

    (其他访问器样式也是可能的,这只是一个示例。但是请注意,我认为从第二个访问器返回 Node const * const & 是不安全的;这可能会编译但它会返回对临时的引用.)

    非常量成员将调用第一个方法,并会看到一个指向可修改Node 的可修改指针。具有 Const 资格的成员将调用第二个,并且认为两者都不可修改。

    【讨论】:

    • 在代码中不是m_firstnode被修改,而是Tree::m_totalnodes通过Tree::GetNode()被修改(最终)。
    • @DoubleYou 但这只是可能的,因为 FindNode 不是 const-qualified 并且它被称为 thorugh m_firstnode。如果您想在不更改 m_totalnodes 的情况下使其工作,您需要添加一个 const 限定的 FindNode,然后通过适当的链接调用它。
    【解决方案2】:

    那个 const 只保证方法本身不会改变数据成员。它没有说明 Node 对象不会更改数据成员(Node 可以,因为它是朋友)。

    【讨论】:

    • 您能再描述一下吗?据我了解,const 方法不能调用任何non-const 方法。如果不是这样的话,那么对于这段代码的客户端,就会产生误导。
    • 这意味着隐含的this指针是const,因此它不能在自身上调用任何非const方法,也不能将this作为非传递给另一个函数-const 指针。
    猜你喜欢
    • 1970-01-01
    • 2018-07-13
    • 2017-01-08
    • 2011-03-13
    • 2013-07-30
    • 2023-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多