类和对象的基本概念
-
什么是类,一系列事物的抽象,万物皆可为类
-
类是有两部分组成: 属性 行为
-
属性: 事物的特征--->数据类型描述
-
行为: 事物的操作--->函数描述
-
-
什么是对象: 类的具体化,类的实例化.
-
类的特点: 封装,继承/派生,多态
类的定义
-
创建语法
-
以下代码紫色部分需要大家牢记,并且记住三个不同的限定词的作用
class 类名 { //权限限定词 public: protected: private: }; //一定有一个;
-
权限限定 作用
-
类外只能访问public属性下面的 东西,习惯把 public属性 叫做类外的接口
-
类外访问 类中的数据,只能通过对象访问,当然static成员除外
-
-
protected和private 类外都不可以访问 ,但是可以提供共有接口间接访问
-
默认属性(没有写在权限限定词下的属性)是 私有属性
-
权限限定词,只是用来限定类外的访问,并不是限定中的访问
-
protected和private 有区别 ,继承有区别,对类外都是不可以访问
-
数据成员一般写成private或者protected,当类不做继承处理时用private
-
-
C++结构体 在一定程序可以直接当作是类
-
结构体默认属性是公有属性,而类默认属性是私有属性
class GirlFriend { public: //共有属性 //成员函数 //类中实现函数 void printData() { cout << m_name << "\t" << m_age << endl; } //为了访问不能访问的部分,通常提供一些接口 void initData(string name, int age); protected: //保护属性 //数据成员 string m_name; private: //当前类不做继承处理,数据成员写成私有属性 int m_age; };
#include <iostream> #include <string> using namespace std; class MM { //如果在这里加入一个public:下面的初始化全为正确 string name; int age; void print() { cout << "不在限定词下的属性" << endl; cout << "默认为私有属性" << endl; } }; int main() { //以下初始化和调用成员函数均报错 //这就是类与结构体默认属性的区别 MM mm; mm.name = "小丽"; //报错 mm.age = 18; //报错 mm.print(); //报错 MM girl = { "小红",20 }; //报错 MM* Friend = new MM; Friend->name = "丽丝"; //报错 Friend->age = 22; //报错 return 0; }
-
要注意,我们在一些代码中也会看到这样的写法,但是这样的写法并没有错
struct MM { int num; //默认属性是公有属性 protected: string name; private: int age; }; int main() { //出现以下情况的原因是因为在结构体中也可以用限定词,这样的写法并没有错误 MM mm; mm.name = "小丽"; //错误 mm.num = 18; //正确 MM* Friend = new MM; Friend->name = "丽丝"; //错误 Friend->num = 22; //正确 return 0; }
对象创建
-
普通对象
-
对象数组
-
new 一个对象
#include <iostream> #include <string> using namespace std; class MM { public: void print() { cout << name << "\t" << age << endl; } void initData(string nname,int nage) { name = nname; age = nage; } protected: //新标准,可以在类中给数据直接初始化 string name="默认值"; int age=0; }; int main() { //没有写构造函数的情况下,和C语言的创建方式是一样的 MM mm; mm.print(); //没有初始化数据 MM mmArray[4]; //一般很少用对象数组 //mmArray[0]----mmArray[3] //数组: 多个变量名有规律,内存连续的变量的集合 for (int i = 0; i < 4; i++) { mmArray[i].initData(string("name") + to_string(i), i + 19); mmArray[i].print(); } //以上循环输出的数据是 /* name0 19 name1 20 name2 21 name3 22 */ MM* p = new MM; p->initData("张三", 18); p->print(); delete p; p = nullptr; return 0; }
成员访问(初始化)
-
通过提供 公有接口传参的方式初始化数据
-
通过提供 公有接口返回值的方式初始化数据(引用函数的用法)
-
默认初始化
class MM { public: //传参 void initData(string name, int age) { m_name = name; m_age = age; } //返回引用 string& getName() //引用函数,返回的是变量本身,可间接进行赋值 { return m_name; } int& getAge() //引用函数,返回的是变量本身,可间接进行赋值 { return m_age; } void print() { cout << m_name << "\t" << m_age << endl; } protected: //默认初始化 string m_name = "默认值"; int m_age = 0; //不做初始化是一个垃圾值 }; int main() { //这种方法是传参的方法进行赋值 MM girl; girl.initData("girl", 19); girl.print(); //这种方法是通过函数返回值来赋值 MM mm; mm.getName() = "mm"; mm.getAge() = 18; mm.print(); //这种方法是通过默认值来赋值 MM boy; boy.print(); return 0; }
面向对象的编程方式
-
下面我将会通过链表的简单创建来体现面向过程和面向对象的不同编程方式
- 我们先用c语言的面向过程的方式来创建链表
#include <iostream> #include <string> using namespace std; struct Node { //链表的结构体 int data; Node* next; }; Node* CreateList() { //创建链表的头结点 Node* HeadNode=new Node; HeadNode->next =NULL; return HeadNode; } Node* CreateNode(int data) { //创建链表结点 Node* NewNode = new Node; NewNode->data = data; NewNode->next = NULL; return NewNode; } void insertData(Node* HeadNode, int data) { //对链表开始插入数据 Node* newNode = CreateNode(data); newNode->next = HeadNode->next; HeadNode->next = newNode; } void printList(Node* headNode){ //对链表的数据开打印 Node* pMove = headNode->next; while (pMove != NULL) { cout << pMove->data << "\t"; pMove = pMove->next; } cout << endl; } int main() { //我们采用头插法的方式来创建链表 Node* List = CreateList(); insertData(List, 20); insertData(List, 30); printList(List); /* 上述操作将输出 30 20 */ return 0; }
-
现在我们再用面向对象的编程方式来创建链表
-
-
但是要注意,面向对象的编程方式创建链表不是只用class ,我们还会用到struct结构体;但是是否可以只用class呢? 答案是可以的。但是我们在访问数据时会比较麻烦
//这里用到了结构体与类结合的方式 #include <iostream> #include <string> using namespace std; struct Node { //链表的结构体 int data; Node* next; }; class List { public: Node* CreateList() { //链表的头指针创建 HeadNode = new Node; HeadNode->next = nullptr; return HeadNode; } void Create(int data) { //链表的链接 Node* NewNode = new Node; NewNode->data = data; NewNode->next = HeadNode->next; HeadNode->next = NewNode; } void printList() { //链表的打印 Node* p = HeadNode->next; while (p != nullptr) { cout << p->data << '\t'; p = p->next; } cout << endl; } protected: Node* HeadNode; //提前把头指针创建在类内 }; int main() { //很明显可以看出来面向对象的编程与面向过程的编程区别还是比较大的 //面向对象的编程方式,我们直接定义一个类类型的指针,通过调用成员函数即可创建链表 List* list = new List; list->CreateList(); list->Create(20); list->Create(30); list->printList(); /*上述的操作输出结果为 30 20 */ return 0; }
//这里仅用了类来做面向对象过程 #include <iostream> #include <string> using namespace std; class Node { public: Node*& GetNext() //引用函数来初始化数据 { return next; } int& GetData() //引用函数来初始化数据 { return data; } protected: int data; Node* next; }; class List { //很明显地看出来,如果全用类来写, //List类中的所有成员函数所需要访问的元素都必须提前定义好函数来访问 public: Node* CreateList() { HeadNode = new Node; HeadNode->GetNext() = nullptr; return HeadNode; } void Create(int data) { Node* NewNode = new Node; NewNode->GetData() = data; NewNode->GetNext() = HeadNode->GetNext(); HeadNode->GetNext() = NewNode; } void printList() { Node* p = HeadNode->GetNext(); while (p != nullptr) { cout << p->GetData() << '\t'; p = p->GetNext(); } cout << endl; } protected: Node* HeadNode; //提前把头指针创建在类内 }; int main() { //很明显可以看出来面向对象的编程与面向过程的编程区别还是比较大的 //面向对象的编程方式,我们直接定义一个类类型的指针,通过调用成员函数即可创建链表 List* list = new List; list->CreateList(); list->Create(20); list->Create(30); list->printList(); /*上述的操作输出结果为 30 20 */ return 0; }