成员函数与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 是 C 语言中一种非常重要的关键字,它可以用来修饰变量、指针、函数返回值、函数参数和成员函数等。 const 的使用可以提高代码的安全性和可读性,本文将对 const 的各种用法进行总结。 1. const 常量 const ...
const 成员函数的返回值也可以是const的,以确保返回值不被修改。 在代码中,我们可以看到一个示例: ```cpp class Testclass { public: char* get_buffer() const { // const 成员函数 return _buf; } private:...
指向成员函数的指针包括成员函数的返回类型,带::符号的类名称,函数参数表。例如: ```c void (A::*pmf)(char *, const char *); typedef void(A::*PMA)(char *, const char *); PMA pmf= &A::strcat; ``` 3. ...
const对象只能访问const成员函数,而非const对象可以访问任意的成员函数,包括const成员函数。 二、static修饰符 static修饰符用于声明静态变量或静态成员函数。 1. 静态变量 静态变量的作用范围在一个文件内,...
* 避免返回指向成员的非const指针或引用的成员函数,以免泄露敏感信息。 * 使用const返回值可以提高函数的安全性。 五、编译器的访问控制 * 劳累的编译器要费九牛二虎之力来确保您设置的访问限制不被破坏。 * 不要...
C++中const用法总结.doc C++中const用法总结.doc 1. const修饰普通变量和指针 2. const修饰函数参数 3. const 修饰函数返回值 4. const修饰类对象/对象...6. const修饰成员函数 7. const常量与define宏定义的区别
3.常量成员函数 常量函数里的const是用来修饰*this的,其形式如下: int f() const{```} 然后这里就有意思了 *this的默认类型是type *const this,this指针有一个顶层const,但并没有底层const,由于低层const的...
8. 指向成员函数的指针:指向成员函数的指针可以采用p=A::f1的方式。 9. 运算符->*的功能:运算符->*的功能是用来表示指向对象指针对指向类成员指针的操作。 10. 指向数组的指针:指向数组的指针可以采用int (*p)...
动态联编要满足两个条件,它们是被调用的成员函数是虚函数、用指针或引用调用虚函数。 9. 抽象类:在C++类中,有一种不能定义对象的类,这样的类只能被继承,称之为抽象类,定义该类至少具有一个纯虚函数。 10. ...
2.常量成员函数,形式:type funname(type1 arg1,type2 arg2,…) const 1)常量成员函数,不能修改类数据成员,不能调用非常量函数。 2)常量成员函数的作用,可以有效的将类的函数分为可以修改类的函数,和不能修改...
05-易犯错误模型-为什么需要成员函数(补充资料)-传智扫地僧 06_课堂答疑类中写成员函数_调用的时才会执行 07_程序设计方法发展历程 08_C语言和C++语言的关系_工作经验分享 09_namespace和iotream 10_实用性加强_...
解释:this指针是指向当前对象的指针,它不可直接作为成员函数的返回值,因为this指针是隐式传递给成员函数的。 5. 在类定义中,private、protected、public可以出现多次。 解释:在C++中,在类定义中,private、...
需要遵守的规则:不能返回局部变量的引用、不能返回函数内部new分配的内存的引用、可以返回类成员的引用,但最好是const。 知识点:函数返回值类型的选择、引用返回值的好处和限制、内存管理和释放。 C/C++笔试和...
+ 使用const与函数结合,实现常参数与返回值为常数的函数。 + 利用const定义常对象,实现常成员函数。 + 分别利用引用与指针实现交换两个数值功能的函数,比较不同。 本实验涵盖了常量和引用的知识,包括常量的...
this 指针是一种隐含指针,隐含于每个类的成员函数中,即调用某成员函数时,都将自动产生一个 this 指针。 七、对象作为函数的参数 在 C++中,可以用对象作为函数的形参或实参。对象作为函数参数的形式有多种,...
类是一种用户自定义的数据类型,类中的成员函数或类的友元函数才能存取类中的私有成员。 13. 执行构造函数的次数 执行 Sample 类的构造函数的次数是 4。 14. 常数据成员 常数据成员的定义形式与一般常变量的定义...
正确答案是 B、在被调用的 num 函数中为实参 x 建立了名为 a 的 const 引用。 知识点:C++ 函数参数传递、引用形式的参数传递 7. 该题考察了 C++ 中的字符串操作,特别是字符串字面量和字符串数组。正确答案是 D、...
3. 使用指针作为函数的参数虽然也能达到与使用引用的效果,但是,在被调函数中同样要给形参分配存储单元,且需要重复使用"* 指针变量名"的形式进行运算,这很容易产生错误且程序的阅读性较差。 四、常引用 如果既...
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 以...
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语句...