Const函数最终通过朋友类修改自己

时间:2014-05-26 02:41:12

标签: c++ tree const

在我的实现中,我有一个主要类Tree,其中包含许多Node个。每个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;
};

2 个答案:

答案 0 :(得分:1)

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

答案 1 :(得分:1)

Node* m_firstnode;

当您调用const之类的GetNode方法时,this会变为const限定类型Tree const *。当您访问m_totalnodes之类的成员时,它们似乎符合const unsigned int const。您无法修改该对象。 m_firstnode变为Node * const:您无法修改指针,但您仍然可以修改它指向的Node

如果您想全面避免意外修改,请通过重载的getter函数访问m_firstnode

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

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

非const成员将调用第一个方法,并将看到指向可修改Node的可修改指针。符合条件的成员将调用第二个,并且看不到可修改的。