返回值为引用或指针的成员函数加const要注意
2013-06-08 12:43
295 查看
成员函数与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;
}
当然,对于在成员函数内部通过指针修改数据的就只能自己注意了。
相关文章推荐
- 条款 30: 避免这样的成员函数:其返回值是指向成员的非 const 指针或引用, 但成员的访问级比这个函数要低
- 类成员变量中存在引用,const,和指针类型时需要注意的事项
- 【从C到C++学习笔记】引用/const引用/引用传递/引用作为函数返回值/引用和指针的区别
- C++,常量,const,constant,引用,指针,形参,实参,函数,返回值
- C++笔记(一)const与define,指针,引用,函数,类成员
- C/C++的区别(默认值、内联函数、函数重载、const、引用、参数、返回值)
- C语言学习9: malloc动态内存存储,动态内存分配去空格字符增长版,动态内存分配去符号incr增长版,型参和返回值都是int型的函数的指针,main函数的地址也可以用指针指向,typedef定义函数指针,函数定义与嵌套的作用,返回函数指针类型,const作用
- [C/C++] const 详解(修饰变量、输入参数、返回值、成员函数)
- 指针作为函数返回值需要注意的情况
- C++点滴——const/volatile不能用来修饰没有this指针的成员函数
- 经典问题解析(1)---const和引用、指针与引用、函数重载、C方式编译
- Delphi函数翻译成VC要注意句柄指针传递(传递Handle的时候,必须加上一个指针引用,才能消除编译错误)
- const限定修饰符用法总结(常量,指针,迭代器,函数参数,成员函数)
- 条款30: 避免这样的成员函数:其返回值是指向成员的非const指针或引用,但成员的访问级比这个函数要低
- 模板类中的成员函数定义返回值为类中的typedef类型时候注意
- 关于函数返回值为引用和指针的问题
- ”引用 & 指针“ -- 作为函数的参数和返回值小结
- const 详解(修饰变量、输入参数、返回值、成员函数)
- 野指针,野引用,const注意,size_t与size_type
- const成员函数和非const成员函数返回引用的问题