一、基本使用方法
在C语言中,数据和算法是分开的关联性不强,在C++中将相互关联的数据和算法封装起来,形成结构体或类,但是结构体和类都是抽象概念,只有定义变量(也叫对象)才会真实存在
所以我们可以说:
类:完成某一功能的数据和算法的集合,是抽象的概念
对象:类的实例,具体的概念,在内存中存在空间的
数据在类中可以称为成员属性,算法可以称为成员函数
//Class是C++中的关键字,类名一般以C开头
Class CPeople //只是抽象的概念
{
public:
string m_strName;
bool m_bSex;
int m_nAge;
void run()
{
cout<<m_strName<<"在跑步"<<endl;
}
};
int main()
{
CPeople peo;//具体的对象,在内存中开辟空间
peo.m_strName="小明";//使用类中属性必须通过对象调用
cout<<peo.m_strName<<endl;
}
二、访问修饰符
访问修饰符:描述类成员可以使用的范围,访问权限
public:公共的,在类内、类外,只要能定义对象的范围都能使用
protected:保护的,在类内和继承的子类使用
private:私有的,只能在类内使用
Class CPeople
{
public:
string m_strName;
protected:
bool m_bSex;
private:
int m_nAge;
public:
void run()
{
cout<<m_strName<<"在跑步"<<endl;
}
//保护私有的在类外无法使用,但是可以建立接口
//设置年龄
void SetAge(int age)
{
m_nage=age;
}
int GetAge()
{
return m_nAge;
}
};
int main()
{
CPeople peo;
peo.m_strName="小明";//公共的
peo.SetAge(30);
cout<<peo.GetAge()<<endl;
}
三、构造函数、析构函数
1.构造函数
(1)作用:用于初始化类中的成员属性
(2)空类中有默认构造函数,函数名是类名,无参数,无返回值,函数中无内容,是编译期默认加的
(3)一般情况下可以手动重构,编译器提供的默认的就不会提供了
(4)类中的构造函数可以有多个,函数体的内容可以根据需求写,多个构造函数是函数重载的关系。定义对象时只能匹配一个
(5)在定义对象时自动调用构造函数,(new出的对象也可以,但是malloc不行)
2.析构函数
作用:在对象生命周期结束时自动回收额外申请的空间,并不是回收对象本身
空类中有默认构造函数,函数名是~类名,无参数,无返回值,函数中无内容,是编译期默认加的
在对象生命结束之前,自动调用(一定是之前)
析构函数只能有一个,而且没有参数
四、封装链表
在C++中, 结构体和类的区别:
1.类的默认访问权限是私有的,结构体默认访问权限是公有的
2.类的默认继承是私有的,结构体默认继承是公有的
#include<iostream>
using namespace std;
struct Node
{
public:
int val;
Node* pNext;
Node(int v)
{
val=v;
pNext=nullptr;
}
};
class CMyList
{
public:
Node* m_pHead;
Node* m_pEnd;
int m_nLen;
CMyList()
{
m_pHead=nullptr;
m_pEnd=nullptr;
m_nLen=0;
}
~CMyList()
{
Node *pTemp=nullptr;
while(m_pHead)
{
pTemp=m_pHead;
m_pHead=m_pHead->pNext;
delete pTemp;
}
m_pHead=nullptr;
m_pEnd=nullptr;
m_nLen=0;
}
public:
void PushBack(int v)
{
Node *pNode=new Node(v);
if(m_pHead)//非空链表
{
m_pEnd->pNext=pNode;
//m_pEnd=pNode;
}
else//空链表
{
m_pHead=pNode;
//m_pEnd=pNode;
}
m_pEnd=pNode;
++m_nLen;
}
void PopFront()
{
Node *pTemp=m_pHead;
if(m_pHead)//链表非空
{
if(m_pHead==m_pEnd)
{
m_pHead=nullptr;
m_pEnd=nullptr;
}
else
{
m_pHead=m_pHead->pNext;
}
delete pTemp;
pTemp=nullptr;
--m_nLen;
}
}
void ShowList()
{
Node *pTemp=m_pHead;
while(pTemp)
{
cout<<pTemp->val<<endl;
pTemp=pTemp->pNext;
}
}
int GetLen()
{
return m_nLen;
}
};
int main()
{
CMyList list;
list.PushBack(1);
list.PushBack(2);
list.PushBack(3);
list.PushBack(4);
list.PushBack(5);
list.ShowList();
cout<<endl;
list.PopFront();
list.ShowList();
list.GetLen();
}
五、对象的种类
全局对象和静态全局对象的区别:
1.全局对象的生命周期从程序创建到程序退出
作用域:整个应用程序(可以跨文件使用)
2.静态全局对象的生命周期从程序创建到程序退出
具有文件作用域,只能在当前文件使用,不能跨文件。
如果想跨文件使用一个静态全局变量,可以借助一个全局的指针
static CTest tst(10);
CTest *ptst=&tst;
extern CTest *ptst;//extern 声明变量的作用
静态局部函数:生命周期从第一次直接调用开始,知道程序退出时结束
多次调用并不会产生多个
只能在当前作用范围内使用,出了这个范围不能直接使用,但是可以间接调用
CTest *pTst=nullptr;
void fun()
{
static CTest tst(50);
if(pTst=nullptr){
pTst=&tst
}
}
cout<<pTst.m_a<<endl;