✨✨欢迎大家来到Celia的博客✨✨
🎉🎉创作不易,请点赞关注,多多支持哦🎉🎉
所属专栏:C++
个人主页:Celia's blog~
一、类的定义
1.1 定义格式
定义类的关键字是class,后面加上类名和一对花括号{},最后还需要在花括号后加上分号。
class Celia //声明一个Celia类
{//类的主体
};//这里要有分号
- 类的主体内叫做类的成员:可以包含各种变量、函数。在类中的变量叫类的属性或成员变量;在类中的函数叫做类的方法或成员函数。
- 在C++中,struct也可以定义类,但是使用class定义类较为常见。
- 在类中实现的所有函数默认是被inline修饰的内联函数。
1.2 访问修饰限定符
C++为了更好的实现封装,会对类中的接口(类中的函数)进行一些访问权限的限制。限制权限的关键字被称为访问修饰限定符。
访问修饰限定符共有三个:
- public
- protected
- private
- public修饰的部分是可以被类外直接访问的;protected和private修饰的部分在目前都是不能在类外直接访问,它们具体的区别需要在后期慢慢学习。
- 访问修饰限定符的范围为从第一个访问修饰限定符开始,到第二个访问修饰限定符结束为止,如果一个修饰符的下面没有出现另一个访问修饰限定符,则作用域到 } 结束。
- 如果类中没有任何访问修饰限定符,class定义的类的默认权限为private,struct定义的类的默认权限为public。
- 一般来说,成员变量都会设置为private,只有供外部使用的函数才会设置为public。
class Celia
{
public://可被类外访问void func(){cout << "public\n" << endl;}
private://不可被类外访问int a;char b;
protected:double c;
};
1.3 类域
类定义了一个新的作用域,类中的所有成员都在类的作用域中。当在类外定义成员函数时,需要使用::操作符指名这个函数是在哪个类域。
class Celia
{
public:void func();//声明与定义分离
private:int a;char b;
protected:double c;};
void Celia::func()//指名在Celia类中
{cout << a << endl;
}
如果上面的函数没有指定在Celia类域中,那么编译器就会把这个函数当作全局函数,编译时会在全局去寻找变量a,找不到就会报错。
二、实例化
2.1 实例化概念
生活中有这样一个例子,我们在建造房子时会有图纸,通过这个图纸可以建造很多个房子。当我们通过类来创建一个对象时,类就像图纸,对象就像房子。类的定义是不占用内存空间的,只有创建对象,才会为这个对象分配内存空间。我们把通过类来创建一个对象的过程叫做类的实例化。
class Celia
{
public:void func();
private:int a;char b;
protected:double c;};
void Celia::func()
{cout << a << endl;
}
int main()
{Celia a;//实例化return 0;
}
2.2 对象的大小
对象中存储的是对象内的各个成员变量,成员函数的指针(指向函数的指针)不包括在内。对象的大小计算方式和C语言的结构体的计算方式是相同的。具体计算方法可以参考这篇文章:自定义类型:结构体。
2.3 对象访问
在类中被public修饰的成员变量和成员函数目前可以用:对象名+ .的方式进行访问。
class Celia
{
public:void func(){cout <<"Celia!"<< endl;}void Init(int a,char b,double c){_a = a;_b = b;_c = c;}
private:int _a;char _b;
protected:double _c;};
int main()
{Celia a;//实例化a.Init(1,'a',1,1);a.func();//访问成员方法cout<< a._a << endl;//访问成员变量return 0;
}
三、this指针
以下代码会实例化两个对象,对这两个对象的成员进行赋值并调用func()成员函数。
class Celia
{
public:void func(){cout << _a << " " << _b << " " << _c << endl;}void Init(int a,char b,double c){_a = a;_b = b;_c = c;}
private:int _a;char _b;
protected:double _c;};int main()
{Celia a;Celia b;a.Init(1, 'a', 3.14);b.Init(2, 'b', 12.5);a.func();b.func();return 0;
}
既然成员函数的指针不储存在对象的内存空间中,那么这个函数如何区分这两个对象的不同成员变量呢?
- 类中的所有函数参数的第一个位置,都会被编译器增加一个当前类类型的指针,叫做this。func函数的原型为:void func(Celia* this);
- 类中的函数访问类中的成员变量都是通过this指针进行访问的,func函数和Init函数内实际的执行代码为:
void func() {cout << this->_a << " " << this->_b << " " << this->_c << endl; } void Init(int a,char b,double c) {this->_a = a;this->_b = b;this->_c = c; }
- 通过哪个对象调用成员函数,这个成员函数的this指针指向的就是哪个对象。
- C++规定不能在实参和形参的位置显示的写this指针(编译时编译器会处理),但是可以在函数体内显示使用this指针。
void func(Celia* this)//error {cout << this->_a << " " << this->_b << " " << this->_c << endl;//√ } /*===================================================================*/ void func() //√ {cout << this->_a << " " << this->_b << " " << this->_c << endl;//√ }