`
dwljd
  • 浏览: 6131 次
  • 性别: 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;
    }


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


分享到:
评论

相关推荐

    const修饰类的成员函数

    这意味着即使一个成员函数被声明为`const`,它也可以返回一个非常量的引用或指针等。 #### 六、总结 通过使用`const`关键字修饰类的成员函数,可以有效地提高程序的安全性和可维护性。它不仅帮助开发者更好地管理...

    虚函数与const指针

    使用虚函数时,必须通过指向基类的指针或基类对象的引用来调用虚函数,其格式为:`指向基类的指针变量名-&gt;虚函数名(实参表)`或`基类对象的引用名.虚函数名(实参表)` 虚函数是C++多态的一种表现形式,例如子类...

    C语言中const使用说明

    然而,对于非`const`变量,即使声明为`const`,如果通过指针或引用绕过`const`限制,仍有可能在程序其他地方修改其值,因此,`const`并不提供绝对的保护。 总结,`const`在C语言中扮演着至关重要的角色,它可以用于...

    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++ const使用详解

    C++ 中的 const 关键字是非常重要的,它可以用来修饰变量、指针、函数参数、返回值、成员函数等,具有非常多的用途。下面将对 const 的使用做详细的解释。 一、const 基础 const 关键字可以用来修饰变量、指针等,...

    c++中const关键字使用详解

    特别是当返回值为对象本身(非引用和指针)时,const的使用多用于二目操作符重载函数产生新对象的时候。 四、类成员函数中的const使用 const关键字在类成员函数中的使用具有特殊含义,它可以声明一个成员函数为...

    使用const提高函数的健壮性

    开发者应当在合适的场景中合理使用const,如函数参数、返回值以及成员函数的定义中,这样不仅提高了代码的安全性,还提高了代码的健壮性和可维护性。在编程实践中,合理利用const可以避免很多不易察觉的错误,尤其在...

    c++里const用法归纳

    需要注意的是,const引用e只能访问声明为const的函数,而不能访问一般的成员函数。 5. Const在函数声明中的应用 Const也可以用来修饰函数的返回值或某个参数,例如: A& operator=(const A& a); void fun0(const ...

    C++中const用法全解

    // 这样作 e 只能访问声明为 const 的函数,而不能访问一般的成员函数 5. const 在函数声明中的应用 const 可以修饰函数的返回值,或某个参数;对于成员函数,还可以修饰整个函数。例如: ```c A& operator=...

    C++中const关键字详解

    `const`成员函数只能访问类中的`const`成员,并且不能修改任何非`const`成员。 #### 五、深入理解`const` 为了更好地理解`const`的含义,我们需要了解它的一些细节: - **位置灵活**: 在声明`const`变量、引用、...

    Const资料整理

    Const 成员函数的定义格式为:`返回值类型 成员函数名 (参数列表) const;` 例如:`void MyClass::Func() const;` Const 成员函数的特点是,它不能修改对象的状态,一旦定义后,任何尝试修改对象状态的操作都会被...

    const T vs. T const

    首先,const关键字可以应用于变量、函数参数、返回值以及类的成员函数等,表示"常量"或"不可变"的意思。当const修饰变量时,该变量的值不允许被修改;当const修饰函数参数时,表示在函数内部不会修改该参数的值;当...

    C++const关键字详解

    值得注意的是,`const`引用不仅可以绑定到`const`对象,也可以绑定到非`const`对象: ```cpp int jj = 123; const int &rjj = jj; // ok ``` #### 四、指针与`const` 指针是C++中处理内存地址的重要工具。`const`...

    函数指针和woid指针详解.docx

    例如,void (A::*pmf)(char *, const char *)是一个指向类A的成员函数的指针变量,传递两个变量char *和const char *,没有返回值。 void指针是C语言中的一种特殊的指针类型,它可以指向任何类型的数据。void指针的...

    指向类的成员函数的指针如何使用(详解)..pdf

    注意操作符`.*`的优先级高于括号,所以必须用括号来确保先执行成员函数指针的解引用。 在继承体系中,如果成员函数是虚函数,那么可以使用基类的指针调用派生类的重写函数,实现动态绑定。然而,非虚函数则始终根据...

    C++中const使用说明

    - 参数中的`const`推荐使用引用或指针,以减少不必要的拷贝。 - 除非特殊情况,否则不要将函数返回值类型设为`const`对象,因为这限制了返回值的可操作性。 - 避免在非操作符重载函数中返回`const`对象的引用,...

    C++中const用法总结.doc

    - 对于类的成员函数,可以声明为`const`成员函数,如`func2()`,表明这个函数不会修改对象状态。 5. **const与#define宏定义的区别** `const`是编译器级别的,提供类型安全检查,而`#define`是预处理器宏,没有...

    CONST用法

    对于类中的成员函数,如果该函数不会修改类的任何成员变量,则应将其声明为`const`成员函数。这样做有两个主要好处: - **安全性**:编译器会检查`const`成员函数是否尝试修改成员变量或调用其他非`const`成员函数,...

    Const 用法小结

    在C++中,`const`关键字有着广泛的应用,它可以用于定义常量、修饰类的数据成员、指针以及函数参数和返回值。以下是关于`const`的一些详细解释: 1. **const 常量**: - `const int max = 100;` 定义了一个名为`...

Global site tag (gtag.js) - Google Analytics