`
dwljd
  • 浏览: 5872 次
  • 性别: Icon_minigender_1
  • 来自: 福建
最近访客 更多访客>>
社区版块
存档分类
最新评论

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

    博客分类:
  • C++
阅读更多

成员函数与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;
    }


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


分享到:
评论

相关推荐

    c语言const用法小结

    const 是 C 语言中一种非常重要的关键字,它可以用来修饰变量、指针、函数返回值、函数参数和成员函数等。 const 的使用可以提高代码的安全性和可读性,本文将对 const 的各种用法进行总结。 1. const 常量 const ...

    const成员函数、初始化列表、static成员1

    const 成员函数的返回值也可以是const的,以确保返回值不被修改。 在代码中,我们可以看到一个示例: ```cpp class Testclass { public: char* get_buffer() const { // const 成员函数 return _buf; } private:...

    c++typedef函数指针类型[文].pdf

    指向成员函数的指针包括成员函数的返回类型,带::符号的类名称,函数参数表。例如: ```c void (A::*pmf)(char *, const char *); typedef void(A::*PMA)(char *, const char *); PMA pmf= &A::strcat; ``` 3. ...

    extern_volatile等修饰符的用法

    const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数。 二、static修饰符 static修饰符用于声明静态变量或静态成员函数。 1. 静态变量 静态变量的作用范围在一个文件内,...

    C++培训教材1

    * 避免返回指向成员的非const指针或引用的成员函数,以免泄露敏感信息。 * 使用const返回值可以提高函数的安全性。 五、编译器的访问控制 * 劳累的编译器要费九牛二虎之力来确保您设置的访问限制不被破坏。 * 不要...

    C++中const用法总结.doc

    C++中const用法总结.doc C++中const用法总结.doc 1. const修饰普通变量和指针 2. const修饰函数参数 3. const 修饰函数返回值 4. const修饰类对象/对象...6. const修饰成员函数 7. const常量与define宏定义的区别

    C++常量详解二(常量形参,常量返回值,常量成员函数)

    3.常量成员函数 常量函数里的const是用来修饰*this的,其形式如下: int f() const{```} 然后这里就有意思了 *this的默认类型是type *const this,this指针有一个顶层const,但并没有底层const,由于低层const的...

    面向对象程序设计C++山师面向对象程序设计试卷A.doc

    8. 指向成员函数的指针:指向成员函数的指针可以采用p=A::f1的方式。 9. 运算符-&gt;*的功能:运算符-&gt;*的功能是用来表示指向对象指针对指向类成员指针的操作。 10. 指向数组的指针:指向数组的指针可以采用int (*p)...

    清华大学计算机系C++期末考试题及答桉归类.pdf

    动态联编要满足两个条件,它们是被调用的成员函数是虚函数、用指针或引用调用虚函数。 9. 抽象类:在C++类中,有一种不能定义对象的类,这样的类只能被继承,称之为抽象类,定义该类至少具有一个纯虚函数。 10. ...

    C++ 常量成员常量返回值详解

    2.常量成员函数,形式:type funname(type1 arg1,type2 arg2,…) const 1)常量成员函数,不能修改类数据成员,不能调用非常量函数。 2)常量成员函数的作用,可以有效的将类的函数分为可以修改类的函数,和不能修改...

    c-c++及数据结构基础视频教程完整版,最适合自学的c++基础

    05-易犯错误模型-为什么需要成员函数(补充资料)-传智扫地僧 06_课堂答疑类中写成员函数_调用的时才会执行 07_程序设计方法发展历程 08_C语言和C++语言的关系_工作经验分享 09_namespace和iotream 10_实用性加强_...

    C++面向对象程序设计期末考试题.doc

    解释:this指针是指向当前对象的指针,它不可直接作为成员函数的返回值,因为this指针是隐式传递给成员函数的。 5. 在类定义中,private、protected、public可以出现多次。 解释:在C++中,在类定义中,private、...

    C/C++笔试、面试题目大汇总

    需要遵守的规则:不能返回局部变量的引用、不能返回函数内部new分配的内存的引用、可以返回类成员的引用,但最好是const。 知识点:函数返回值类型的选择、引用返回值的好处和限制、内存管理和释放。 C/C++笔试和...

    11427-C++面向对象程序设计-实验指导书[整理].pdf

    + 使用const与函数结合,实现常参数与返回值为常数的函数。 + 利用const定义常对象,实现常成员函数。 + 分别利用引用与指针实现交换两个数值功能的函数,比较不同。 本实验涵盖了常量和引用的知识,包括常量的...

    2023年面向对象程序设计实验指导书实.doc

    this 指针是一种隐含指针,隐含于每个类的成员函数中,即调用某成员函数时,都将自动产生一个 this 指针。 七、对象作为函数的参数 在 C++中,可以用对象作为函数的形参或实参。对象作为函数参数的形式有多种,...

    C++选择题填空题.doc

    类是一种用户自定义的数据类型,类中的成员函数或类的友元函数才能存取类中的私有成员。 13. 执行构造函数的次数 执行 Sample 类的构造函数的次数是 4。 14. 常数据成员 常数据成员的定义形式与一般常变量的定义...

    C++语言考试题试卷 练习题 模拟题 选择题 含答案 2014年选择题复习.docx

    正确答案是 B、在被调用的 num 函数中为实参 x 建立了名为 a 的 const 引用。 知识点:C++ 函数参数传递、引用形式的参数传递 7. 该题考察了 C++ 中的字符串操作,特别是字符串字面量和字符串数组。正确答案是 D、...

    C、C++笔试题集锦+.pdf

    3. 使用指针作为函数的参数虽然也能达到与使用引用的效果,但是,在被调函数中同样要给形参分配存储单元,且需要重复使用"* 指针变量名"的形式进行运算,这很容易产生错误且程序的阅读性较差。 四、常引用 如果既...

    零起点学通C++多媒体范例教学代码

    6.9 const成员函数 6.10构造函数 6.11默认构造函数 6.12析构函数 6.13析构对象数组 6.14总结 第7章 循环语句 7.1 循环语句的前身——goto语句 7.2 慎用goto语句 7.3 while语句 7.3.1 带运算符的while语句 7.3.2 以...

    零起点学通C++学习_多媒体范例教学代码

    6.9 const成员函数 6.10构造函数 6.11默认构造函数 6.12析构函数 6.13析构对象数组 6.14总结 第7章 循环语句 7.1 循环语句的前身——goto语句 7.2 慎用goto语句 7.3 while语句 7.3.1 带运算符的while语句...

Global site tag (gtag.js) - Google Analytics