对于不改变类内部成员的成员函数,我们都要在函数后面加上const,对于会改变数据成员的函数则不加const。对成员函数加上const有明确的限制行为:调用该成员函数不会改变内部数据成员。但是,如果const函数的返回值是引用或指针呢?这种情况到底要不要对返回值加上const呢?先来看一段示例:
?
class="cpp" name="code">#include <iostream> using namespace std; struct Node { Node* next; int value; Node() : next(0), value(0){ } }; class TestList { typedef Node* node_ptr; typedef const Node* const_node_ptr; private: node_ptr header; public: TestList() : header(0){ } TestList(node_ptr n) : header(n){ } void print() const { node_ptr tmp = header; while (tmp != 0){ cout << tmp->value << (tmp->next == 0 ? "" : ", next: "); tmp = tmp->next; } cout << endl; } void setHeader(node_ptr n) { header = n; } node_ptr getHeaderPtr() const { return header; } node_ptr& getHeaderRef() const { return (node_ptr&)header; } }; int main(int argc, char** argv){ Node header; header.value = 1; TestList tl(&header); // tl.setHeader(&header); cout << "tl ori: " << endl; tl.print(); Node* nptr = tl.getHeaderPtr(); nptr->value = 2; cout << "tl node value can modify by pointer: " << endl; tl.print(); Node refNode; refNode.value = 3; refNode.next = &header; tl.getHeaderRef() = &refNode; cout << "tl node can modify by reference: " << endl; tl.print(); cout << "---------------------- const object ----------" << endl; const TestList ctl(&header); //tl.setHeader(&header); cout << "ctl ori: " << endl; ctl.print(); nptr = ctl.getHeaderPtr(); nptr->value = 5; cout << "ctl node value can modify by pointer: " << endl; ctl.print(); Node crefNode; crefNode.value = 6; crefNode.next = &header; ctl.getHeaderRef() = &crefNode; cout << "ctl node can modify by reference: " << endl; ctl.print(); }
上面示例代码的输出结果:
?
tl ori: 1 tl node value can modify by pointer: 2 tl node can modify by reference: 3, next: 2 ---------------------- const object ---------- ctl ori: 2 ctl node value can modify by pointer: 5 ctl node can modify by reference: 6, next: 5
由以上输出可以看到,通过修改const成员函数返回的引用或指针可以修改对象内部的值。这与const函数只能读取内部数据成员(加mutable的数据成员不包括在内)是否相矛盾呢?const函数本身是不会修改数据成员的,但是通过它的返回值可以在外部修改对象内部数据。如果对象是non-const的,这种情况还可以接受;但是如果对象是const的,这种情况就不是所期望的了。
?
要防止这种情况发生可以对返回值加const,或者对于在类内部需要把返回值作为左值的则把访问级别限制为public以下(需要再外部修改数据成员的,则提供修改器)。如:
?
const_node_ptr getHeaderPtr() const { return header; } const node_ptr& getHeaderRef() const { return (node_ptr&)header; }
或
?
protected: node_ptr getHeaderPtr() const { return header; } node_ptr& getHeaderRef() const { return (node_ptr&)header; }
当然,对于在成员函数内部通过指针修改数据的就只能自己注意了。
网友 2014/5/29 21:55:41 发表
垃圾排版