在我的实现中,我有一个主要类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;
};
答案 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
的可修改指针。符合条件的成员将调用第二个,并且看不到可修改的。