类的引入
C语言结构体中只能定义变量,在C++中,结构体内不仅可以定义变量,也可以定义函数。例如:在学习数据结构时用C
语言实现了一个栈,在实现的过程中,结构体中只定义了变量,函数都是在外部实现的,现在以C++的方式实现的话,相
关联的函数就可以在结构体的内部实现。
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将会代替struct的作用
类的定义
class className
{
// 类体:由成员函数和成员变量组成
}; // 一定要注意后面的分号
class为定义类的关键字,ClassName为类的名字,{ }中为类的主体,注意类定义结束后不要忘记后面的分号。
类体中的内容为类的成员:类中的变量为类的属性,类中的函数称为类的方法或者类的成员函数
类的两种定义方式:
1.声明和定义全部放在类体中,需注意:成员函数如果在类中定义,编译器可能会将其当成内联函数来处理
class Person1
{
public:
void showinfo()
{
std::cout << _name << '-' << _sex << '-' << _age << std::endl;
}
char* _name;
char* _sex;
int _age;
//声明和定义全部放在类体中·
};
2.类声明放在.h文件中,成员函数定义放在.cpp文件中,注意:成员函数名前面要加类名
//person.c
#include "person.h"
void Person::showinfo()
{
std::cout << name << '-' << sex << '-' << age << std::endl;
}
class Person
{
public:
void showinfo();
public:
char* name;
char* sex;
int age;
};
一般情况下,更期望采用第二种方式。
类的访问限定符及封装
访问限定符
C++实现封装的方式:用类将对象的属性和方法结合在一起,让对象更加完善,通过访问权限,将访问接口选择性的提供给外部的用户使用。
【访问限定符说明】
1.public修饰的成员在类外可以直接被访问
2.protected和private修饰的成员在类外不能直接被访问(此处protected和pravate是类似的)
3.访问权限作用于从该访问限定符出现的位置开始直到下个访问限定符为止
4.后面如果没有访问限定符,作用域到}为止
5.class的默认访问权限为private,struct为public(因为struct要兼容C)
**注意:访问限定符只在编译的时候有用,当数据映射到内存上时没有任何访问限定符的区别
封装
封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅通过对外开放的接口来进行交互
封装本质上是一种管理,让用户更方便使用类
类的作用域
类定义了一个作用域,类的所有成员都在类的作用域中,在类体外定义成员时,需要使用::作用域操作符指名成员属于哪个类域
class Person
{
public:
void showinfo();
public:
char* name;
char* sex;
int age;
};
//这里需要指名showinfo属于Person这个类域
void Person::showinfo()
{
std::cout << name << '-' << sex << '-' << age << std::endl;
}
类的实例化
用类类型创建对象的过程,称为类的实例化
1.类是对对象进行描述的,是一个模型一样的东西,限定了类有哪些成员,定义出一个类并没有分配实际的内存空间来储存它
2.一个类可以实例化出很多对象,实例化出的对象需要占据实际的空间,用于储存成员变量
this指针
this指针的引出
class Date
{
public:
void init(int year, int month, int day)
{
_year = year;
_month = month;
_day = day;
}
void show()
{
std::cout << _year << '-' << _month << '-' << _day << std::endl;
}
private:
int _year;
int _month;
int _day;
};
void test1()
{
Date d1;
d1.init(2023, 9, 7);
d1.show();
}
此段代码问题在于在调用show()函数的时候是如何调用的是d1的属性的呢?
C++中通过引入this指针解决该问题,即:C++编译器给每个“非静态成员函数”增加了一个隐藏的指针参数,让该指针指向当前对象(函数运行时调用的对象),在函数体中所有“成员变量”的操作,都是通过该指针去访问。只不过所有的操作对用户是不透明的,即用户不需要来传递,编译器自动完成。
this指针的特性
1.this指针的类型为 类类型* const,及成员函数中不能给this指针赋值,也不能改变this指针的值
2.只能在成员函数的内部使用
3.this指针本质上是“成员函数”的形参,当对象调用成员函数时,将对象地址作为实参传递给this形参。所以对象中不存储this指针
4.this指针是“成员函数”第一个隐含的指针形参,一般情况有编译器通过ecx寄存器自动传递,不需要用户传递