C++类和对象(五)

本文详细介绍了C++中动态内存管理的关键字new和delete,以及它们与malloc的区别,强调了不要混用new和free。同时,文章讲解了如何使用new分配和初始化基本类型、数组类型以及对象,以及如何正确释放内存。此外,还阐述了静态成员的概念,包括静态成员变量和静态成员函数的特性,以及如何通过静态成员计算类的实例化对象个数。
摘要由CSDN通过智能技术生成

知识点1.new和delete关键字

1、new和malloc(变种calloc、realloc)比较:

①malloc返回一个void指针,C++不允许将void赋值给其他任何指针,必须强转;

②malloc可能申请内存失败,所以必须判断返回值来确保内存分配成功;

③malloc不会调用构造函数,free不会调用析构函数。

注意:new、delete和malloc、free不要混搭使用。

2、new给基本类型分配空间,delete释放空间

void test01()
{
    int *p = NULL;
    //给基本类型分配空间,p = (int *)calloc(1, sizeof(int));
    p = new int;
    *p = 100;
    cout << "*p = " << *p << endl;
    //释放,free p;
    delete p;
}

3、new给数组类型分配空间并初始化

语法:基本类型 *变量名 = new 基本类型[数组个数];

注意,new时有[],delete释放时也必须有[]

void test02()
{
    int *arr = NULL;
    //给数组类型分配空间,并初始化
    //arr = (int *)calloc(5, sizeof(int));
    arr = new int[5]{1, 2, 3, 4, 5};
    for (int i = 0; i < 5; i ++)
    {
        cout << arr[i] << " ";
    }
    cout << endl;
    //释放,new时有[],释放时delete也要加[]
    delete[] arr;
}

4、new从堆区实例化对象

#include <cstring>
class Student{
private:
    char *Name;
    int Age;
public:
    Student()
    {
        Name = NULL;
        cout << "无参构造" << endl;
    }
    Student(char *name, int age)
    {
        Name = new char[32];
        strcpy(Name, name);
        Age = age;
        cout << "有参构造" << endl;
    }
    ~Student()
    {
        cout << "析构函数" << endl;
        if (Name != NULL) delete[] Name;
    }
    void showStudent()
    {
        cout << "Name = " << Name << ",Age = " << Age << endl;
    }
};
void test03()
{
    //new给类申请空间,如果申请成功,就会自动调用类的构造函数
    Student *stu = new Student("lucy", 20);
    stu->showStudent();
    //delete先调用析构函数,再释放空间
    delete stu;
}

结果:

5、对象数组:本质是数组,每个数组元素是类的对象

定义对象数组时,系统会给数组中的每个元素调用构造函数,未初始化时,默认调用无参构造;初始化时,初始化部分调用有参构造,未初始化部分默认调用无参构造。

void test04()
{
    //对象数组
    Student *stu = new Student[5]{ Student("lucy",20), Student("bob",18) };
    stu[0].showStudent();
    (stu + 1)->showStudent();
    delete [] stu;
}

结果:

6、尽量不要使用delete释放void *,因为无法从void中寻找响应的析构函数

void test05()
{
    Student *stu = new Student("lucy",17);
    stu->showStudent();
    //万能指针,void *
    void *stu1 = stu;
    delete stu1;
}

结果:

知识点2.静态成员(static定义的成员)

在类的定义中,使用static定义的成员(包括成员变量和成员函数)是静态的,成为静态成员;在类的对象创建过程中,静态成员只有一个拷贝,所有类的对象共享这个拷贝。

1、静态成员变量

静态成员变量属于某个类,为所有该类的对象所共享,必须在类中声明,在类外定义。静态数据成员不属于某个对象,在为对象分配空间时不包括静态成员所占空间。

class Data{
private:
    //类的静态成员属性
    static int Num;
public:
    int other;
    static int data;
};
//类外初始化,不需要加static
int Data::Num = 0;
int Data::data = 0;

void test01()
{
    //通过类名直接访问
    Data::data = 10;
    cout << "Data::data = " << Data::data << endl;

    //通过对象访问
    Data d1, d2;
    d1.data = 20;
    cout << "d1.data = " << d1.data << endl;
    cout << "d2.data = " << d2.data << endl;

    //普通成员变量是属于对象的,只能通过对象名访问
    d1.other = 100;
    cout << "d1.other = " << d1.other << endl;
    cout << "d2.other = " << d2.other << endl;//d2.other未初始化
    //cout << "Data::other = " << Data::other << endl;//err

    //静态成员也有访问权限,类外不能访问私有成员
    //cout << "Data::Num = " << Data::Num << endl;//err
    //cout << "d1.Num = " << d1.Num << endl;//err
}

结果:

2、静态成员函数

静态成员函数的目的是操作静态成员数据,不能访问非静态成员数据,但普通成员函数可以操作静态成员数据;静态成员函数和静态成员变量都有权限之分。

class Data{
private:
    int Num;//普通成员变量
    static int Other;//静态成员变量
public:
    //静态成员函数
    static int getOther()
    { 
        //Num = 10;//err,静态成员函数不能访问非静态成员数据
        return Other;
    }
};
//静态成员变量类外定义+初始化
int Data::Other = 10;

void test01()
{
    //通过类名称直接访问静态成员函数
    cout << "Data::getOther = " << Data::getOther() << endl;
    //通过对象名访问静态成员函数
    Data d;
    cout << "d.getOther = " << d.getOther() << endl;
}

结果:

3、const修饰静态成员数据时,即实现成员数据共享,又使成员数据不可改变,最好在类内部初始化;在类外部初始化时,同样需要加上const修饰。

4、案例:通过静态成员计算实例化对象个数

#include <iostream>

using namespace std;

class Data{
private:
    static int Count;
public:
    Data(){
        Count ++;
        cout << "无参构造" << endl;
    }
    ~Data(){
        Count --;
        cout << "析构函数" << endl;
    }
    static int getCount(){ return Count; }
};

int Data::Count = 0;

int main()
{
    Data ob1;
    Data ob2;
    {
        Data ob3;
        Data ob4;
        cout << "实例化对象的个数:" << Data::getCount() << endl;
    }
    cout << "实例化对象的个数:" << Data::getCount() << endl;
    return 0;
}

结果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值