C++面向对象 Part 1
文章目录
面向对象的概念
C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。C++是基于面向对象的,更关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完成。
类的引入
C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。比如:之前在数据结构初阶中,用C语言方式实现的栈,结构体中只能定义变量;现在以C++方式实现,会发现struct中也可以定义函数
eg:
typedef int DataType;
struct Stack
{
void Init(size_t capacity)
{
_array = (DataType*)malloc(sizeof(DataType) * capacity);
if (nullptr == _array)
{
perror("malloc申请空间失败");
return;
}
_capacity = capacity;
_size = 0;
}
void Push(const DataType& data)
{
// 扩容
_array[_size] = data;
++_size;
}
DataType Top()
{
return _array[_size - 1];
}
void Destroy()
{
if (_array)
{
free(_array);
_array = nullptr;
_capacity = 0;
_size = 0;
}
}
DataType* _array;
size_t _capacity;
size_t _size;
};
int main()
{
Stack s;
s.Init(10);
s.Push(1);
s.Push(2);
s.Push(3);
cout << s.Top() << endl;
s.Destroy();
return 0;
}
在C++中我们更习惯将结构体写作class
类的定义:
定义:
class为定义类的关键字,ClassName为类的名字,{}中为类的主体,注意类定义结束时后面分
号不能省略。类体中内容称为类的成员:类中的变量称为类的属性或成员变量; 类中的函数称为类的方法或者
成员函数。
定义方式:
类的定义方式有两种
- 声明和定义全部放在类体中,需注意:成员函数如果在类中定义,编译器可能会将其当成内
联函数处理。 - 类声明放在.h文件中,成员函数定义放在.cpp文件中,注意:成员函数名前需要加类名::
一般情况下,还是更推荐使用第二种方式,更符合规范些
类的访问限定符及封装
类的限定符有三种:public,private,protected
限定符说明:
- public修饰的成员在类外可以直接被访问
- protected和private修饰的成员在类外不能直接被访问(此处protected和private是类似的)
- 访问权限作用域从该访问限定符出现的位置开始直到下一个访问限定符出现时为止
- 如果后面没有访问限定符,作用域就到} 即类结束。
- class的默认访问权限为private,struct为public(因为struct要兼容C)
【面试题】
面向对象的三大特性:封装、继承、多态。
类如何进行实例化
说明:类的定义就是对对象的描述,其规定了实例化出来的对象具有什么样的属性(成员变量)、什么样的行为(成员方法)…类就好像是一个模板一样,按这个模板造出来的东西,他们可能属性不同,但是归根结底都是同一类,另外类不占用空间的,只有他在实例化出来对象后,对象才会占用空间,除此之外,类的定义就是存在于代码段的。
类对象模型:
如何计算类对象的大小-内存对齐
class A
{
public:
void PrintA()
{
cout<<_a<<endl;
}
private:
char _a;
};
Q:类中既可以有成员变量,又可以有成员函数,那么一个类的对象中包含了什么?如何计算类占用空间的大小?
A:实际上,我们可以通过程序来实际打印下一个类的大小,我们发现,他的大小只占用了成员变量的大小,这是因为在C++中类的存储策略是每个类的属性可能不一样,但是他们成员方法都一样,所以就给类开辟属性占用大小的空间,然后方法统一保存在一个地方,这样可以节省栈空间资源的开辟。这就好比在一个单元楼里,每家都要有厨房,但是每家不用都有健身房一个道理好吧。大家灵性理解为主。
Q:类的大小计算规则?
A:类的大小遵循内存对齐规则,和结构体内存对齐方式一样,我在C语言板块详细介绍过,有兴趣可以去看看
【面试题】
- 结构体怎么对齐? 为什么要进行内存对齐?
- 如何让结构体按照指定的对齐参数进行对齐?能否按照3、4、5即任意字节对齐?
- 什么是大小端?如何测试某台机器是大端还是小端,有没有遇到过要考虑大小端的场景
这里着重针对为什么要内存对齐来说明下,因为机器设计的原因,读取内存只能从整数倍的地址开始读取,如果不存在内存对齐,每个成员都是前帮贴后背的在内存里。有这么中情况:
class{
char a;
int b;
}
this指针
this指针的特性:
1. this指针的类型:类类型 const,即成员函数中,不能给this指针赋值。*
- 只能在“成员函数”的内部使用
- this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给
this形参。所以对象中不存储this指针。 - this指针是“成员函数”第一个隐含的指针形参,一般情况由编译器通过ecx寄存器自动传
递,不需要用户传递
this指针是如何传递的?
this指针是C++编译器给每个“非静态的成员函数“增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用该函数的对象),在函数体中所有“成员变量”的操作,都是通过该指针去访问。只不过所有的操作对用户是透明的,即用户不需要来传递,编译器自动完成。
C++中通过类可以将数据 以及 操作数据的方法进行完美结合,通过访问权限可以控制那些方法在类外可以被调用,即封装,在使用时就像使用自己的成员一样,更符合人类对一件事物的认知。而且每个方法不需要传递class的参数了,编译器编译之后该参数会自动还原,即C++中 class 参数是编译器维护的,C语言中需用用户自己维护。