- 类是一种用户自定义的复合数据类型,即包括表达属性的成员变量,也包括表达行为的成员函数
- 类可用于表达那些不能直接与内置基本类型建立自然映射关系的逻辑抽象
- 类是现实世界的抽象,对象是类在虚拟世界的实例
在C++中,类(class)和结构(struct)已没有本质性的差别,唯一的不同在于
类的缺省访问控制属性为私有(private)
结构的缺省访问控制属性为公有(public)
访问控制限定符仅作用于类,而非作用于对象。
对不同成员的访问控制属性加以区分,体现了C++作为面向对象程序设计语言的封装特性
我们创建一个对象后会给这个对象分配内存空间,然后定义占据这部分内存空间的成员变量。
// 类:抽取事物特征的规则
#include
#include
using namespace std;
//struct
class Human {
public:
void setinfo( int age=0, const char* name="无名" ) {// 桥梁函数
if( !strcmp(name,"憨憨") ) {
cout << "你才憨呢" << endl;
return;
}
m_age = age;
strcpy( m_name, name );
}
void getinfo() {
cout << "姓名:" << m_name << ", 年龄:" << m_age << endl;
}
private:
int m_age; // 声明
char m_name[256]; // 声明
};
// 以上的代码模拟类的设计者(C++标准库提供,第三方提供,自己设计的)
// ------------------------------------------------
// 以下的代码模拟类的使用者
int main( void ) {
Human h; // 定义h(给h分配内存空间)
// 在h所占内存空间中 定义m_age,初值为随机数
// 在h所占内存空间中 定义m_name,初值为随机数
cout << "h对象的大小:" << sizeof(h) << endl; // 260
h.setinfo( 22, "张飞" );
h.setinfo( 22, "憨憨" );
h.getinfo();
// h.m_age = 22;
// strcpy( h.m_name, "张飞" );
// strcpy( h.m_name, "憨憨" );
// cout << "姓名:" << h.m_name << ", 年龄:" << h.m_age << endl;
return 0;
}
C++对象模型
- 同一个类的不同对象各自拥有一份独立的成员变量。
- 同一个类的不同对象彼此共享同一份成员函数。
- 那么在代码区中,被同一个类的不同对象所共享的成员函数,在这些成员函数内部,如何区分其所访问的成员变量隶属于哪个对象?
C++成员函数模型
- 类的每个成员函数(除静态成员函数外),都有一个隐藏的指针型参数,形参名为 this,指向调用该成员函数的对象,这就是this指针.
- 在类的成员函数中(除静态成员函数外),对所有成员的访问,都是通过this指针进行的
// 类:抽取事物特征的规则
#include
#include
using namespace std;
// 当前程序有2个对象(h/h2),每个对象各有一份成员变量(m_age/m_name),共有两份成员变量
class Human {
public: // _ZN5Human7setinfoEiPKc
void setinfo( /* Human* this */ int age=0, const char* name="无名" ) {
this->m_age = age;
strcpy( this->m_name, name );
}
void getinfo( /* Human* this */ ) { // _ZN5Human7getinfoEv
cout << "姓名:" << this->m_name << ", 年龄:" << this->m_age << endl;
}
private:
int m_age; // 声明
char m_name[256]; // 声明
};
// 以上的代码模拟类的设计者(C++标准库提供,第三方提供,自己设计的)
// ------------------------------------------------
// 以下的代码模拟类的使用者
int main( void ) {
Human h; // 定义h(给h分配内存空间)
// 在h所占内存空间中 定义m_age,初值为随机数
// 在h所占内存空间中 定义m_name,初值为随机数
cout << "h对象的大小:" << sizeof(h) << endl; // 260
h.setinfo( 22, "张飞" ); // _ZN5Human7setinfoEiPKc(&h,...);
h.getinfo(); // _ZN5Human7getinfoEv(&h)
Human h2; // 定义h2(给h2分配内存空间)
// 在h2所占内存空间中 定义m_age,初值为随机数
// 在h2所占内存空间中 定义m_name,初值为随机数
cout << "h2对象的大小:" << sizeof(h2) << endl; // 260
h2.setinfo( 25, "关羽" );// _ZN5Human7setinfoEiPKc(&h2,...);
h2.getinfo();// _ZN5Human7getinfoEv(&h2)
return 0;
}
- 多数情况下,程序并不需要显式地使用this指针
- 有时为了方便,将类的成员变量与该类成员函数的参数取相同标识符,这时在成员函数内部,可通过this指针将二者加以区分
- 返回基于this指针的自引用,以支持串连调用
- 将this指针作为函数的参数,以实现对象交互
// 必须自己写this的情况
#include
using namespace std;
class Integer; // 短式声明
void Print( Integer* v ) {
// ...
}
class Integer {
public:
void setinfo( /* Integer* this */ int i ) {
this->i = i; // (1)必须自己添加this
}
void getinfo( /* Integer* this */ ) {
cout << /*this->*/i << endl; // 这里的this编译器补
Print( this ); //(3)必须自己写this
}
Integer& increment( /* Integer* this */ ) {
++/*this->*/i;
return *this; //(2) 返回基于this指针的自引用
}
private:
int i;
};
// 以上的代码模拟类的设计者(C++标准库提供,第三方提供,自己设计的)
// ------------------------------------------------
// 以下的代码模拟类的使用者
int main( void ) {
Integer ix;
ix.setinfo( 666 );
ix.getinfo();
ix.increment().increment().increment(); // 串联调用
ix.getinfo();
return 0;
}
Integer& increment( /* Integer* this */ ) {
++/*this->*/i;
return *this; //(2) 返回基于this指针的自引用
}
this 指针是一个指向当前对象的指针。对于返回基于 this 指针的自引用的 increment() 方法,它返回的是当前对象本身的引用,因此可以理解为返回的是对象 ix 的引用。
每次调用 increment() 都返回当前对象的引用(也就是 ix 的引用)。因为返回的是引用,所以每次调用 increment() 后,你可以继续对返回的对象(即 ix)调用 increment()。这使得你能够像 ix.increment().increment().increment(); 这样的串联调用。
void getinfo() {
Print(this); // 这里的 `this` 是指向当前 Integer 对象的指针
}
Integer ix;
ix.getinfo();
所以,当前对象就是 ix,而this 指向的也是 ix。