类与对象感悟

本文深入解析C++中的类与对象概念,包括类的定义、成员访问、构造与析构函数、深浅拷贝等核心知识点,并通过一个学生成绩管理系统实例演示类的应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

  类是一种将抽象转换为用户定义类型的c++工具,它将数据表示和操纵数据的方法组合成一个简洁的包,

c++是对具有相同属性和行为的一组对象的抽象与统一描述,是用户自定义的数据类型格式:

注:类的最后一定加“;”。

类和对象的定义与访问

1.定义类和对象

  C++中,类定义的说明语句一般形式为:

class<类名>

{

  public:

         公有段数据成员和成员函数;

  protected:

         保护段数据成员和成员函数;

  private:

         私有段数据成员和成员函数;

};

注:

类成员用关键字指定不同的访问特性,决定其在类体系中或类外的可见性。

private用于声明私有成员。私有成员只能在类中可见,不能在类外或派生类中使用。

protected声明保护成员。保护成员在类和它的派生类中可见。

public声明公有成员。公有成员是类的接口,在类中和类外可见。

例:

clas Date

{

public:

    voidSetDate(int y,int m,int d);

    int IsLeapYear();

    void PrintDate();

private:

    int year,month,day;

};

2.访问对象成员

  使用对象包括访问对象的数据成员和调用成员函数。类中的成员函数可以使用自身不同性质的数据成员和调用成员函数。公有成员是提供给外部的接口,即,只有公有成员在类体系外可见。对象成员的访问形式与访问结构的形式相同,运算符“.”和“->”用于访问对象成员。

3.this指针

  一般来说,所有类方法都将this指针设置为调用它的对象的地址;

  当参数与成员变量名相同时,如this->x = x,不能写成x = x。

构造函数和析构函数

构造函数和析构函数的原型是:

  类名::类名(参数表);

  类名::~类名();

1.构造函数

默认构造函数是一个空函数。

注:

构造函数可以重载。

构造函数可以有任意类型的参数,但没有返回类型。

通常,利用构造函数创建对象有以下两种方法:

(1) 利用构造函数直接创建对象.其一般形式为:

          类名 对象名[(实参表)];

          这里的“类名”与构造函数名相同,“实参表”是为构造函数提供的实际参数。 

(2)利用构造函数创建对象时,通过指针和new来实现。其一般语法形式为:

      类名 *指针变量 = new 类名[(实参表)];

2.析构函数

析构函数的定义格式如下(类外实现): 

类名::~类名()

{

      函数语句

}

若没有显式定义析构函数,则系统自动生成一个默认形式的析构函数。

系统自动生成的默认构造函数形式如下: 

类名::~类名(){}

一般情况下,可以不定义析构函数

但如果类的数据成员中包含指针变量是从堆上进行存储空间分配的话,需要在析构函数中进行存储空间的回收

注:
构函数与构造函数名字相同,但它前面必须加一个波浪号(~)。
析构函数没有参数,也没有返回值,而且不能重载。因此在一个类中只能有一个析构函数。
当撤消对象时,编译系统会自动地调用析构函数。 

浅复制:

在用一个对象初始化另一个对象时,只复制了数据成员,而没有复制资源,使两个对象同时指向了同一资源的复制方式称为浅复制。
即:对于复杂类型的数据成员只复制了存储地址而没有复制存储内容
默认复制构造函数所进行的是简单数据复制,即浅复制 。

深复制:

通过一个对象初始化另一个对象时,不仅复制了数据成员,也复制了资源的复制方式称为深复制。
自定义复制构造函数所进行的复制是浅复制。 

1.深复制构造函数必须显式定义

2.深复制构造函数的特点

①定义:类名::类名([const]类名 &对象名);

②成员变量的处理:对复杂类型的成员变量,使用new操作符进行空间的申请,然后进行相关的复制操作

常成员:

在类的尘缘函数后面加const关键字,则该成员函数成为常量成员函数 

类型说明符函数名(参数表) const;

在数据成员前面加上const,成为常数据成员

静态成员函数

除静态数据成员以外,一个类还可以有静态成员函数。

静态函数仅可以访问静态成员,

或是静态成员函数或是静态数据成员。

静态成员函数和静态数据成员一样,它们都属于类的静态成员,它们都不是对象成员。因此,对静态成员的引用不需要用对象名。

静态成员函数没有this指针,只能对静态数据操作

定义静态成员函数的格式如下:

    static返回类型静态成员函数名(参数表);

与静态数据成员类似,调用公有静态成员函数的一般格式有如下几种:

    类名::静态成员函数名(实参表)

    对象. 静态成员函数名(实参表)

    对象指针->静态成员函数名(实参表)

友元函数

如果在本类(类A)以外的其他地方定义了一个函数(函数B)

这个函数可以是不属于任何类的非成员函数,

也可以是其他类的成员函数,

在类体中用friend对其(函数B)进行声明,此函数就称为本类(类A)的友元函数。

友元函数(函数B)可以访问这个类(类A)中的私有成员。

在此附上第一个系统:(学生成绩查询)

#include<iostream>
#include<string>
#include<algorithm>
using namespace std;
class student
{
    string name;
    int no;
    int score[3];
    float average;
    int order;
public:
    student(int id,string na,int x,int y,int z):name(na),no(id)
    {
        score[0]=x,score[1]=y,score[2]=z;
        order=-1,average=(score[0]+score[1]+score[2])/3;
    }
    student()
    {
        score[0]=score[1]=score[2]=0;
        order=-1,average=0;
    }
    int getNo()
    {
        return no;
    }
    float getAverage()
    {
        return average;
    };
    void setAverage(int avg)
    {
        average=avg;
    }
    void setOrder(int x)
    {
        order=x;
    }
    int getOrder()
    {
        return average;
    };
    string getName()
    {
        return name;
    }
    void setName(string name)
    {
        this->name=name;
    }
    void display();
};
void student::display()
{
    cout<<name<<"\t"<<no<<"\t"<<score[0]<<"\t"<<score[1]<<"\t"<<score[2]<<"\t"<<average<<"\t\t"<<order<<endl;
}
bool cmp1(student stu1,student stu2)
{
    if(stu1.getAverage()-stu2.getAverage()>=1e-9) return 1;
    else return 0;
}
bool cmp2(student stu1,student stu2)
{
    return stu1.getNo()<stu2.getNo();
}
class student_list
{
    student list[60];
    int n;
public:
    student_list():n(0) {};
    void add();
    void deleteStu();
    void query();
    void change();
    void display(int flag);//flag=1,成绩按学号排列。flag=0,成绩按名次排列
    void menu();
    int search(int no);//按学号查找。找到返回在成绩表中的位置,否则返回-1
    void sortList();
};
//该函数的功能是添加一个或者多个同学基本信息。
void student_list::add()
{
    int no,x,y,z;
    string name;
    system("cls");
    cout<<" 按学号、姓名、数学、英语、c++顺序输入学生信息,学号输-1表示结束"<<endl;
    while((cin>>no)&&no!=-1)
    {
        cin>>name>>x>>y>>z;
        student s(no,name,x,y,z);
        list[n++]=s;
        sortList();
    }
}
//该函数的功能是对改变了的成绩表进行名次更新。结果可以按名次排列也可按学号排列
void student_list::sortList()
{
    sort(list,list+n,cmp1);
    int i;
    for(i=0; i<n; i++)
        list[i].setOrder(i+1);
}
void student_list::display(int flag)//flag=1,按学号排列; flag=0,按名次排列
{
    if(flag) sort(list,list+n,cmp2);
    else sort(list,list+n,cmp1);
    cout<<"姓名"<<"\t"<<"学号"<<"\t"<<"数学"<<"\t"<<"英语"<<"\t"<<"c++"<<"\t"<<"平均成绩"<<"\t"<<""<<endl;
    for(int i=0; i<n; i++)
        list[i].display();
}
int student_list::search(int no)
{
    int i;
    for(int i=0; i<n; i++)
        if(list[i].getNo()==no)
            return i;
    return -1;
}
void student_list::query()
{
    int no,i;
    system("cls");
    cout<<"请输入要查询同学的学号,按-1结束查询:";
    while(cin>>no&&no!=-1)
    {
        i=search(no);
        if(i!=-1)
        {
            cout<<"姓名"<<"\t"<<"学号"<<"\t"<<"数学"<<"\t"<<"英语"<<"\t"<<"c++"<<"\t"<<"平均成绩"<<"\t"<<"名次"<<endl;
            list[i].display();
            cout<<"请输入要查询的同学的学号,按-1结束查询:";
        }
        else cout<<"学号输入有误,请重输,输入-1结束查询"<<endl;
    }


}
//该函数的功能是实现按学号进行修改操作,并输出查找的结果
void student_list::change()
{
    int no,i,x,y,z;
    string name;
    system("cls");
    cout<<"请输入要修改同学的学号,按-1结束查询:";
    while (cin>>no&&no!=-1)
    {
        i=search(no);
        if(i!=0)


        {
            cout<<"修改后同学的姓名 数学 英语 c++"<<endl;
            cin>>name>>x>>y>>z;
            student s(no,name,x,y,z);
            list[i]=s;
            sortList();
            cout<<"请输入要修改同学的学号,按-1结束查询:";
        }
        else cout<<"学号输入有误,请重输,输入-1结束查询"<<endl;
    }


}


void student_list::deleteStu()
{
    {
        int i,no,a;
        system("cls");
        cout<<"请输入要删除同学的学号,按-1结束查询:";
        while (cin>>no&&no!=-1)
        {
            if(i!=-1)
            {
                cout<<"姓名"<<"\t"<<"学号"<<"\t"<<"数学"<<"\t"<<"英语"<<"\t"<<"c++"<<"\t"<<"平均成绩"<<"\t"<<"名次"<<endl;
                list[i].display();
                cout<<"请输入要查询同学的学号,按-1结束查询";
            }
            else
                cout<<"学号输入有误,请重输,输入-1结束查询"<<endl;
        }
    }
}
int main()
{
    student s(1,"ff",66,77,88);
    s.display();
    cout<<s.getAverage()<<endl;
    s.setName("方法");
    s.display();
    student_list c;
    c.add();
    c.display(1);
    c.query();
    c.display(0);
    c.change();
    c.deleteStu();
    return 0;

}

总结:

  类与对象就像是给各个程序明确分类了各种功能,进而组成了整个系统,虽然说出来感觉有点和上一次的感悟相似,但这却实让我想到了初高中生物学的生命层次方面人体的系统由各种脏器组成,各种脏器各司其职。这种想法越发让我感觉学习和大自然的关系颇为玄妙。。。难度方面确实感到加大了,但是现阶段我感觉主要是编程量的加大让我感觉有些不适应,以后勤加练习这种状况应该会有所改善。为自己加油!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值