为什么const对象只能调用const成员函数,而不能调用非const成员函数?
2016-10-07 11:49
411 查看
参考:http://www.cnblogs.com/cplinux/articles/5553716.html
http://blog.csdn.net/lanxuezaipiao/article/details/41647333#comments
在c++中,我们可以用const来定义一个const对象,const对象是不可以调用类中的非const成员函数,这是为什么呢?下面是总结的一些原理。
假设有一个类,名字为test代码如下:
我们知道c++在类的成员函数中还会隐式传入一个指向当前对象的this指针,所以在test类中,实际的print函数应该是这样的void print(test * this);,这代表一个指向test对象的指针this被传入到了print函数中
假如现在我们用test类创建一个对象,
第二句,obj1.print();其实相当于print(&obj1);,即把当前的对象obj1的指针传递到print()函数,这是没问题的
如果用test类创建一个const对象,然后去调用print()函数呢?这就会出现问题
这时obj2对象的指针就会传递给test *this 指针,而obj2的地址翻译成指针类型应该是这样的,const test* this,即这时会出现类型不匹配的错误,在visual studio 中会出现类似于下面的错误:
4
所以通过上面的说明,我们知道了为什么const 对象不能调用非const成员函数。
下面解释为什么const 对象可以调用const成员函数,
前面我们把非const成员函数print(),翻译了一下,同样const成员函数也要翻译,void print()const; 可以翻译成 void print(const test* this);,那么常量对象的地址翻译是const test* this; 是和void print() const;中this指针的类型是一样的,所以常量对象可以调用const成员函数。
有一个点要注意,在c++中其实是有最小权限原则的,非const对象是可以调用const成员函数的。
任何不修改成员数据的函数应该声明为const函数,这样它可以由const对象使用。
注意:构造函数和析构函数都不是const成员函数,因为它们在初始化和清理时,总是对对象作些修改。
如果我们想要建立一个const成员函数,但仍然想在对象里改变某些数据,这时该怎么办呢?这关系到按位const和按成员const的区别。按位const意思是对象中的每个位是固定的,所以对象的每个位映像从不改变。按成员const意思是,虽然整个对象从概念上讲是不变的,但是某个成员可能有变化。当编译器被告知一个对象是const对象时,它将保护这个对象。
这里我们要介绍在const成员函数里改变数据成员的两种方法。
第一种方法已成为过去,称为“强制转换const”。它以相当奇怪的方式执行。取this(这个关键字产生当前对象的地址)并把它强制转换成指向当前类型对象的指针。看来this已经是我们所需的指针,但它是一个const指针,所以,还应把它强制转换成一个普通指针,这样就可以在运算中去掉常量性。下面是一个例子:
这种方法可行,在过去的程序代码里可以看到这种用法,但这不是首选的技术。问题是:this没有用const修饰,这在一个对象的成员函数里被隐藏,这样,如果用户不能见到源代码(并找到用这种方法的地方),就不知道发生了什么
class Y {
int i, j;
public:
Y() { i = j = 0; }
void f() const;
};
void Y::f() const {
//! i++; // error
((Y*)this)->j++; // ok , cast away const feature.
}
第二种方法也是推荐的方法,就是在类声明里使用关键字
class Y {
int i;
mutable int j;
public:
Y() { i = j = 0; }
void f() const;
};
void Y::f() const {
//! i++; // error
((Y*)this)->j++; // ok , mutable.
}
http://blog.csdn.net/lanxuezaipiao/article/details/41647333#comments
在c++中,我们可以用const来定义一个const对象,const对象是不可以调用类中的非const成员函数,这是为什么呢?下面是总结的一些原理。
假设有一个类,名字为test代码如下:
1 class test{ 2 int i; 3 public: 4 void print(); 5 test(int i); 6 };
我们知道c++在类的成员函数中还会隐式传入一个指向当前对象的this指针,所以在test类中,实际的print函数应该是这样的void print(test * this);,这代表一个指向test对象的指针this被传入到了print函数中
假如现在我们用test类创建一个对象,
1 test obj1(12); 2 obj1.print();
第二句,obj1.print();其实相当于print(&obj1);,即把当前的对象obj1的指针传递到print()函数,这是没问题的
如果用test类创建一个const对象,然后去调用print()函数呢?这就会出现问题
const test obj2(122); obj2.print();
这时obj2对象的指针就会传递给test *this 指针,而obj2的地址翻译成指针类型应该是这样的,const test* this,即这时会出现类型不匹配的错误,在visual studio 中会出现类似于下面的错误:
4
所以通过上面的说明,我们知道了为什么const 对象不能调用非const成员函数。
下面解释为什么const 对象可以调用const成员函数,
1 class test{ 2 public: 3 void print()const; 4 };
前面我们把非const成员函数print(),翻译了一下,同样const成员函数也要翻译,void print()const; 可以翻译成 void print(const test* this);,那么常量对象的地址翻译是const test* this; 是和void print() const;中this指针的类型是一样的,所以常量对象可以调用const成员函数。
有一个点要注意,在c++中其实是有最小权限原则的,非const对象是可以调用const成员函数的。
任何不修改成员数据的函数应该声明为const函数,这样它可以由const对象使用。
注意:构造函数和析构函数都不是const成员函数,因为它们在初始化和清理时,总是对对象作些修改。
引申:如何在const成员函数里修改成员 —— 按位和与按成员const
如果我们想要建立一个const成员函数,但仍然想在对象里改变某些数据,这时该怎么办呢?这关系到按位const和按成员const的区别。按位const意思是对象中的每个位是固定的,所以对象的每个位映像从不改变。按成员const意思是,虽然整个对象从概念上讲是不变的,但是某个成员可能有变化。当编译器被告知一个对象是const对象时,它将保护这个对象。这里我们要介绍在const成员函数里改变数据成员的两种方法。
第一种方法已成为过去,称为“强制转换const”。它以相当奇怪的方式执行。取this(这个关键字产生当前对象的地址)并把它强制转换成指向当前类型对象的指针。看来this已经是我们所需的指针,但它是一个const指针,所以,还应把它强制转换成一个普通指针,这样就可以在运算中去掉常量性。下面是一个例子:
这种方法可行,在过去的程序代码里可以看到这种用法,但这不是首选的技术。问题是:this没有用const修饰,这在一个对象的成员函数里被隐藏,这样,如果用户不能见到源代码(并找到用这种方法的地方),就不知道发生了什么
class Y {
int i, j;
public:
Y() { i = j = 0; }
void f() const;
};
void Y::f() const {
//! i++; // error
((Y*)this)->j++; // ok , cast away const feature.
}
第二种方法也是推荐的方法,就是在类声明里使用关键字
mutable,以指定一个特定的数据成员可以在一个const对象里被改变。
class Y {
int i;
mutable int j;
public:
Y() { i = j = 0; }
void f() const;
};
void Y::f() const {
//! i++; // error
((Y*)this)->j++; // ok , mutable.
}
相关文章推荐
- 为什么const对象只能调用const成员函数,而不能调用非const成员函数?
- 为什么const对象只能访问const成员函数
- C++之const对象只能调用const成员函数---补充(18)《More Effective C++》
- 为什么const对象只能访问const成员函数
- C++的const类成员函数(解释为什么非const成员函数不能访问const对象的数据成员)
- 为什么const对象只能访问const成员函数
- const 对象只能调用 const 函数
- cons对象/指针/引用,不能调用非const成员函数
- objective-c中自己创建的对象为什么不能调用release
- C++中const引用的是对象的时候只能调用该对象的f()const方法
- 项目中的错误:const对象只能调用const函数
- 为什么对于类的const成员,只能使用初始化列表,而不能在构造函数内部进行赋值操作
- C++中const引用的是对象的时候只能调用该对象的f()const方法
- 1. const 之 const 型对象只能调用const型成员
- 调用线程对象的start()方法会执行run(),为什么不能直接调用run()方法??
- const类型对象只能调用const类型函数
- C++细节学习之const对象只能调用const函数
- 为什么对象不能调用Object的方法?
- [C++] const对象只能调用const方法的原因
- 为什么在DllMain里不能调用LoadLibrary和FreeLibrary函数?