当前位置:首页 > 开发 > 编程语言 > 编程 > 正文

返回值为引用或指针的成员函数加const要注意

发表于: 2013-06-08   作者:dwljd   来源:转载   浏览次数:
摘要: 成员函数与const 对于不改变类内部成员的成员函数,我们都要在函数后面加上const,对于会改变数据成员的函数则不加const。对成员函数加上const有明确的限制行为:调用该成员函数不会改变内部数据成员。但是,如果const函数的返回值是引用或指针呢?这种情况到底要不要对返回值加上const呢?先来看一段示例: 代码示例与结果   #include <iostream&

成员函数与const

对于不改变类内部成员的成员函数,我们都要在函数后面加上const,对于会改变数据成员的函数则不加const。对成员函数加上const有明确的限制行为:调用该成员函数不会改变内部数据成员。但是,如果const函数的返回值是引用或指针呢?这种情况到底要不要对返回值加上const呢?先来看一段示例:

代码示例与结果

 

#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;
    }


当然,对于在成员函数内部通过指针修改数据的就只能自己注意了。


返回值为引用或指针的成员函数加const要注意

  • 0

    开心

    开心

  • 0

    板砖

    板砖

  • 0

    感动

    感动

  • 0

    有用

    有用

  • 0

    疑问

    疑问

  • 0

    难过

    难过

  • 0

    无聊

    无聊

  • 0

    震惊

    震惊

编辑推荐
#include <iostream> using namespace std; class base1 { public: virtual void fun1a() con
一、构造函数初始化列表 推荐在构造函数初始化列表中进行初始化 构造函数的执行分为两个阶段 初始化
C++中得指针总是那么微妙,下面是我对关键字“const”修饰指针的一些理解。 通过const修饰指针有三
前面有一篇文章讲了指针与引用。并且还提到不能定义指向引用的指针(因为引用不是对象,没有实际的地
前言 这是改造前一篇 设计模式 的基础,使通知者不必知道观察者的类名和函数名,只需要知道更新函数
前言 这是改造前一篇 设计模式 的基础,使通知者不必知道观察者的类名和函数名,只需要知道更新函数
C++中函数的参数相比C语言中的函数参数要复杂的多,其中主要的原因是C++中引入了引用以及const限定
指针与引用的差别: 1.非空区别。在任何情况下,都不能使用指向空值的引用。 2.合法性区别。在使用
一 概括 指针和引用,在C++的软件开发中非常常见,如果能恰当的使用它们能够极大的提高整个软件的效
  复习数据结构的时候看到指针的引用,两年前学的细节确实有点想不起来,于是查了一下网上的资料
版权所有 IT知识库 CopyRight © 2009-2015 IT知识库 IT610.com , All Rights Reserved. 京ICP备09083238号