鸦领主 发表于 2021-1-17 16:57:13

C++构造函数 析构函数 链表类练习

本帖最后由 鸦领主 于 2021-1-19 16:22 编辑

1.构造函数是类的一种特殊成员函数,分为有参数,无参数和拷贝构造函数。
a)无参数构造函数:主要用来在创建对象时初始化对象
类名()
{
要初始化的数据

};

b)有参数构造函数:不需要再做一个函数将数据再带进去
类名(参数表)
{
要初始化的数据

};
    Sdate(int i, int c, int t)
    {
      n = i, y = c, r = t;
    }
Sdate d1(2020, 1, 1); //这样可以直接将数据带入进去,不需要再做一个函数将数据再带进去
c)拷贝构造函数:用一个已有对象初整体始化新的对象(系统有默认的拷贝构造函数,如果没有定义函数,系统也会拷贝)
标准拷贝构造函数定义:类名(const 类名 &参数)
不标准拷贝构造函数定义:类名(类名 &参数)
    Sdate(Sdate &d)
    {
      memcpy(this, &d, sizeof(Sdate));
    }模拟系统拷贝构造函数

2.析构函数:对象所在的函数已调用完毕时,系统自动执行析构函数。
无论是栈空间还是全局空间系统都会自动清理
程序员只要考虑申请过的堆空间进行释放
~类名()
{

};
~Sdate()//析构函数
    {
       //要进行释放堆空间的代码
    }

3.静态成员变量:
对象的内存中包含了成员变量,不同的对象占用不同的内存,这使得不同对象的成员变量相互独立,它们的值不受其他对象的影响。例如有两个相同类型的对象 a、b,它们都有一个成员变量 m_name,那么修改 a.m_name 的值不会影响 b.m_name 的值。
在C++中,我们可以使用静态成员变量来实现多个对象共享数据的目标。使用关键字static修饰

class Student {
public:
    int Test;//成员变量(定义)
    static int nStatic;//静态成员变量(声明)
};

#include "Sdt.h"
int Sdt::nStatic;//在类外定义一下,就能使用了
int main()
{
    Sdt s1, s2;
    s1.add(10);
    s1.add(20);//s1加起来是30
    s2.add(10);
    s2.add(20);//s2加起来是30
}

int Sdt::add(int n)
{
    nStatic += n;//但是nStatic不属于类对象它会把4个数值都加起来
    Test += n;
    return nStatic;
}


static 成员变量既可以通过对象来访问,也可以通过类来访问。请看下面的例子:
    Sdt s1, s2;
//通过类来访问
    Sdt::nStatic = 10;//此时Sdt::nStatic是10
//通过对象来访问
    s1.nStatic = 20;//此时Sdt::nStatic是20这俩种方式的写法是等效的

4.友元函数friend
其他函数或则类也能够访问某个类内的非公有成员
a)对某个类开放friend 类名//对这个类进行开放
b)对全局函数开放 friend 函数//main函数里面可以使用,有参数要带参数
c)对莫格函数开放 friend 函数 //这个函数可以使用


5.编写一个链表类
支持构造函数,析构函数,析构时将改链表的所有节点删除
支持,添加信息,打印信息,定义多个链表对象循环使用不同的链表对象进行添加和打印
#include<iostream>
using namespace std;
struct Data
{
    char name;
    char zhha;
    char mima;
};
struct list
{
    Data data;
    list* next;
};
class Sdata
{
    list* m_pHead;
    void tail(Data data)//从尾部插入一个节点
    {
      list* p = new list;
      p->data = data;
      p->next = NULL;
      if (!p)
      {
            m_pHead = p;
            return;
      }
      list* p1 = m_pHead;
      while (p1)
      {
            p1 = p1->next;
      }
      p1->next = p;
    }
    void head(Data data)//从头部插入一个节点
    {
      list* p = new list;
      p->data = data;
      p->next = m_pHead;
      m_pHead = p;
    }
    void Clear()//释放堆内存空间,
    {
      list* p = m_pHead,*p1;
      while (p)
      {
            p1 = p;
            p = p->next;
            delete p1;
      }
      m_pHead = NULL;
    }
    void add() //添加一系列信息
    {
      Data data;
      cout << "请输入你要添加的名称,账号,密码:" << endl;
      cin >> data.name >> data.zhha >> data.mima;
      head(data); //在调用heda函数添加到堆空间里面
    }
    void print()//打印系列信息
    {
      list* p = m_pHead;
      while (p)
      {
            cout << p->data.name << p->data.zhha << p->data.mima << endl;
            p = p->next;
      }
    }
public:
    Sdata()//构造函数,将m_phead初始化为空
    {
      m_pHead = NULL;
    }
    ~Sdata()//析构函数,系统在快结束的时候会自动调用
    {
      Clear();//每次执行清理堆空间
    }
    void meun()//菜单栏
    {
      cout << "1.添加信息" << endl;
      cout << "2.浏览信息" << endl;
      cout << "请选择:" << endl;
      int i = 0;
      cin >> i;
      switch (i)
      {
      case 1:
            add();
            break;
      case 2:
            print();
            break;
      }
    }
};

int main()
{
    Sdata s1, s2; //俩个链表对象
    int i = 1;
    while (i!=0)
    {
      cout << "请选择链表1,或则链表2" << endl;
      cin >> i;
      switch (i)
      {
      case 1:
            s1.meun();
            break;
      case 2:
            s2.meun();
            break;
      }
    }
    return 0;
}

4.添加类

类试图-添加-添加类

输入类名
生成一个.h文件后和.cpp文件,可以将结构体 链表和类放进去放进.h中

可以添加函数,添加之后会在.h中出现声明。.cpp编写函数代码

5.将上面代码放进添加的类里面,并且编写删除,保存,加载,查找功能
删除
void Sdata::Delete()
{
    char name;
    cout << "请输入要删除的信息名称:" << endl;//假如要删除第二个数据
    cin >> name;
    list* p = m_pHead;
    if (strcmp(p->data.name, name) == 0);//如果删除的数据是第一个
    {
      m_pHead = p->next;//将它指向的下一个节点变成头节点
      delete p;//在删除这个节点
      pres();//保存
      return;
    }
    list* p1 = NULL;//在定义一个指针
    while (p)
    {
      if (strcmp(p->data.name, name))//因为删除的不是第一个数据,第一次并不会进入if
      {
            p1->next = p->next;//此时将输入的第一个数据指向的地址,赋值为输入的第三个数据
            delete p;//在删除第二个数据
            pres();//保存
            return;
      }
      p1 = p;//将p1(NULL)等于p(输入的第一个数据)
      p = p->next;//p在等于p指向的下一个地址
    }
}查找
void Sdata::lookup()
{
    system("cls");
    list* p = m_pHead;
    char name;
    cout<<"请输入你要查找的软件:";
    cin >> name;
    while (p)
    {
      if (strcmp(p->data.name, name) == 0)
            printf("软件名:%s 账号:%s 密码:%s", p->data.name, p->data.zhha, p->data.mima);
      p = p->next;
    }
    system("pause");
}保存
void Sdata::pres()
{
    FILE* p = fopen("data", "w");//写入数据到data文件,如果没有data则会生成一个data文件
    list* p1 = m_pHead;
    while (p1)
    {
      fwrite(&p1->data, 1, sizeof(p1->data), p);//将data里面的数据写入到文件,
      p1 = p1->next;
    }
    fclose(p);//与文件 断开连接
}加载
void Sdata::load()
{
    FILE* p = fopen("data", "r");//读取data文件里面的内容
    if (!p)
      return;
    Data data;
    while (fread(&data,1,sizeof(data),p)==sizeof(data))//读取到data内存地址上
      head(data);//读取的内容,从头部添加到堆上
    fclose(p);
}


页: [1]
查看完整版本: C++构造函数 析构函数 链表类练习