目录
前言:
一、类概念的引入
二、类的定义
三、类的访问限定符与封装
1、访问限定符
2、封装
四、类的作用域
五、类的实例化
六、类的大小
七、类的this指针
this指针的特性
前言:
C++与它的老朋友C语言不同,C语言是面向过程的,主要关注的是分析解决问题的步骤,通过不断的用函数调用去解决问题。
而C++是一款面向对象的语言,把问题拆解成许多对象,通过对象间的交互来解决问题。
拿同样是洗衣服这件事情来举例,C语言是关注:拿洗衣盆->放水->放衣服->放洗衣粉->手搓......的过程。而C++是关注:人,洗衣粉,衣服,洗衣盆这四个对象,通过对象自己间的交互来完成洗衣服这件事情。
一、类概念的引入
C语言中有个结构体的概念,可以代表人,玫瑰花,狮子等不同的事物。但是我们只能在这里面定义成员变量,也就是说,我们在C语言中定义的人,只会被我们赋予年龄,性别,身高等属性。但在C++中,我们可以在结构体中额外定义成员函数,相当于我们赋予了人抬手,蹲下,做饭,结婚等动作。
这使不同的结构体之间可以有所交互,这就是C++的面向对象特性的主要特点。
//C语言中的人
struct People
{int age;char name[10];char gender[10];//......
};
//C++中的人
struct People
{
public:void Grow_up();//长大void Get_Marry();//结婚//.......
private:int age;char* name;char* gender;//......
};
在上面我们可以分别看见在C语言与C++环境下的People结构体的定义。但是C++中,我们一般用class来代替struct,我们通常称class为一个类。虽然C++同样可以使用struct结构体,但两者有些差别,我会在后面给大家补充。
二、类的定义
class是我们定义类所使用的关键字,使用方法跟定义结构体类似,我们可以在类的主体部分定义成员变量与成员函数。
类通常有两种定义方式,第一种就是声明与定义全部放在类体中,但需要注意的是,如果函数是在类里面定义的,编译器可能默认会将函数处理成内联函数。
第二种方法就是类声明放在.h头文件中,定义放在.cpp源文件上,一般来说,除非迫不得已,我们更推荐使用第二种定义方式。但需要注意的是,由于类域的限制,我们在.cpp文件中写定义的时候,要在函数名前加上类名::
这一点就跟C语言模拟实现栈,队列等数据结构一样。
三、类的访问限定符与封装
1、访问限定符
类的限定访问符有三种,分别是:public,protected,private。
public修饰的成员在类外可以直接被访问,而protected与private修饰的成员不能再类外直接被访问。对于class类来说,默认的访问权限为private,而struct为了兼容C语言,默认的访问权限就为public。
C++用类将对象的属性与方法结合在一起,使对象更加完善,实现了封装。在此的基础上,通过访问限定符选择性的提供类与外界的接口给用户使用。
访问限定符的主要作用是在编译时检查和限制对类成员的访问,以确保程序的数据封装性和安全性。在程序运行时,访问限定符不会影响类成员在内存中的存储方式,而是在编译阶段起作用。在内存中,无论类的成员是私有的、保护的还是公有的,它们在内存中的存储方式和布局是相同的。这是因为在内存中,类的对象通常是按照其声明顺序依次存储的,而不考虑访问限定符。
2、封装
C++作为一个面向对象的语言,具有三大特性:封装,继承,多态。
在我们类和对象中,主要研究的是封装这个特性。
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性与实现细节,仅对外公开接口来实现与对象的交互。
这使得C++语言更加贴近生活,就像是我们的电脑,我们用户看不到它的内部组成结构,但可以通过开机键,关机键,鼠标与键盘来操纵电脑的运行。
四、类的作用域
类所定义的的新的作用域,叫作类域。类中的所有成员,不管是公开、保护还是私有,都在类的作用域中。当我们在类外定义类的成员,时,就需要通过::作用域操作符来访问该类的成员。
class Person
{
public:void Print();
private:char _name[20];char _gender[20];int _age;
};void Person::Print()
{cout << _name << ' ' << _gender << ' ' << _age << endl;
}
像这个代码,当我们在类域外定义它的成员函数时,就需要在函数名前加Person::来指定所属的类域,如此才能查到这个函数的声明。
五、类的实例化
用类类型创建变量的时候,就是类的实例化。
只有当类创建了对象,才会分配内存空间。类就像是模具,种类一般的东西,对象就是种类中的个体成员。
一个类可以实例化出多个对象,就如同定义一个内置类型的变量一般,类名加上对象名,就是一个对象了。
六、类的大小
类跟C语言中的结构体还是有所不相同,既具有成员变量,又具有成员函数,那么我们应该如何计算一个类的大小呢?
一个类可以有多个对象,每个对象中的成员变量的值可能有所不同,但成员函数都相同,若是成员函数的大小也纳入了类的大小中,那么岂不是重复存储了太多相同函数,这样岂不是很浪费空间。
class A1
{
public:void fun(){;}
private:int a;char b;int c;
};class A2
{
public:void fun(){;}
private:int a;int c;
};class B
{
public:void fun(){;}
};class C
{};int main()
{cout << sizeof(A1) << endl << sizeof(A2) << endl << sizeof(B) << endl << sizeof(C) << endl;return 0;
}
对于以上代码,输出结果为
对于有成员变量的类,计算类的大小的方法就跟结构体内存对齐之后的大小类似,但当一个类是空类,或者说类只含有成员函数,那么这个类的大小就只会开辟一个字节大小的空间来存储这个类。
也就是说,类的大小并不包含他所有的成员函数,类的大小就是它所有成员变量内存对齐后的大小。(空类与没有成员变量的类的大小都为1)。
类的大小需要通过内存对齐计算,这里的内存对齐就是指的我们在C语言阶段学的结构体内存规则,忘记了的可以去翻一下C语言结构体的讲解。
(http://t.csdnimg.cn/louR8)
七、类的this指针
为了区分一个类中的不同对象,C++编译器给每个类中非静态的成员函数都提供了一个隐藏起来的this指针,这个指针指向了该对象本身。在调用这个函数时,如果需要用到该对象本身的成员变量,就可以通过调用this指针来使用。
class Date
{
public:void init(){_year = 1900;_month = 1;_day = 1;}void Print(){cout << _year << ' ' << _month << ' ' << _day << endl;}private:int _year;int _month;int _day;
};int main()
{Date A;A.init();A.Print();return 0;
}
我们定义了一个简单的日期类,在用成员函数的时候,我们并没有传参,那么它怎么知道我们调用的是哪个对象的数据呢?
这里就是我们this指针的功劳了。
这里的代码实际是
class Date
{
public:void init(){this->_year = 1900;this->_month = 1;this->_day = 1;}void Print(){cout << this->_year << ' ' << this->_month << ' ' << this->_day << endl;}private:int _year;int _month;int _day;
};
由于this是指向这个对象的指针,所以我们可以轻松调用它的成员变量。
this指针的特性
1、this指针的类型为 类类型*const,这就意味着我们不能在成员函数调用this时更改this所指向的对象。
2、只能在成员函数的内部使用。
3、this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给 this形参。
4、this指针是隐藏的,在编译时编译器会自动处理,所以不需要用户进行传递。
——————————————————————————————————————————
以上就是关于类与对象(上)知识点的总结与讲解,希望那个对大家有所帮助!