类和对象
类的一般形式
访问控制限定符
- public 公有成员,谁都可以访问
- protected 保护成员,只有类自己和子类可以访问
- private 私有成员,只有类自己可以访问
类和结构的访问控制限定符区别
- 类的缺省访问控制限定为私有(private)
- 结构的缺省访问控制限定为公有(public)
封装
访问控制限定符仅作用于类,而非作用于对象。
对不同成员的访问控制限定加以区分,体现了C++作为面向对象程序设计语言的封装特性。
对象创建过程
定义xxxx: 就是给xxx分配内存空间
Person p;
该语句定义了变量p,且给p在栈分配了内存空间,成员属性初值为随机数。
成员函数的this指针
C++对象模型
- 同一个类的不同对象各自拥有一份独立的成员变量
- 同一个类的不同对象彼此共享同一份成员函数
- 哪个对象调用成员函数,成员函数的this指针就指向哪个对象
C++成员函数模型
- ( 除静态成员函数外)类的每个成员函数,都有一个隐藏的指针型形参,形参名为 this.
- this形参指向调用该成员函数的对象,一般将其称之为this指针
- ( 除静态成员函数外)在类的成员函数内部,对所有成员的访问都是通过this指针进行的.
应用
- 多数情况下,程序并不需要显式地使用this指针
- 有时为了方便,将类的成员变量与该类成员函数的参数取相同标识符这时在成员函数内部,可通过this指针将二者加以区分
- 返回基于this指针的自引用,以支持串连调用
#include <iostream>
#include <cstring>
using namespace std;
class Integer{
public:
void setInfo(/* Integer* this */int i){
this->i = i; // 这里必须显式添加this (1)
}
void getInfo(/* Integer* this */){
cout << /*this->*/i << endl; // 这里编译器会补this
}
Integer& increment(/* Integer* this */){
++/*this->*/i; // 这里编译器会补this
return *this; // 返回基于this指针的自引用(这里必须自己显式写this) (2)
}
private:
int i; // m_i
};
// 以上代码模拟类的实现者
// -----------------------
// 以下代码模拟类的使用者
int main( void ) {
Integer ix;
ix.setInfo(1000);
ix.getInfo();
ix.increment().increment().increment(); // 串联调用
ix.getInfo();
return 0;
}
常对象和常函数
常对象:
被const关键字修饰的对象、对象指针或对象引用,统称为常对象
常函数:
在类成员函数的形参表之后,函数体之前加上const关键字,则该成员函数的this指针即具有常属性,这样的成员函数被称为常函数
原型相同的成员函数,常版本和非常版本构成重载
- 非常对象优先选择非常版本,如果没有非常版本,也能选择常版本
- 常对象只能选择常版本
在常函数内部无法修改成员变量的值,除非该成员变量被mutable关键字修饰
// 常对象(被const修饰的对象、指针、引用)和非常对象(没有被const修饰的对象、指针、引用)
// 常函数(编译器补的this参数有const修饰)和非常对象(编译器补的this参数没有const修饰)
#include <iostream>
#include <cstring>
using namespace std;
class Integer{
public:
void setInfo(/* Integer* this */int i){ // 非常函数
m_i = i;
}
void getInfo(/* Integer* this */){ // 非常函数
cout << "非常函数getInfo:" << m_i << endl;
}
void getInfo(/* const Integer* this */)const{ // 常函数
const_cast<Integer*>(this)->m_i = 666;
cout << "常函数getInfo: " << m_i << endl;
}
private:
/*mutable*/ int m_i;
};
// 以上代码模拟类的实现者
// -----------------------
// 以下代码模拟类的使用者
int main( void ) {
Integer ix; // ix是非常对象
Integer* pix = &ix; // pix是非常对象
Integer& rix = ix; // rix是非常对象
ix.setInfo(1000);
ix.getInfo(); // getInfo(&ix)-->实参为Integer* 非常对象优先选择非常函数,也可以选择常函数
const Integer cix = ix; // cix是常对象
const Integer* pcix = &cix; // pcix是常对象
const Integer& rcix = cix; // rcix是常对象
cix.getInfo(); // getInfo(&cix)-->实参是const Integer* 常对象只能选择常函数,不能选择非常函数
return 0;
}