本文主要是介绍C++中类的相关学习,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
动态内存分配和回收(堆区)
C语言中动态内存分配和回收使用malloc函数和free函数完成的
C++依旧可以使用上述的两个函数完成,动态内存分配和回收
C++也可以使用两个关键字new和delete来完成动态内存的分配和回收
内存分配
单个申请
格式:数据类型 *指针名 = new 数据类型
int *p1 = new int; //在堆区申请了int类型大小的空间,并将地址赋值给p1
例:
//在堆区申请了int类型大小的空间,并将地址赋值给p1int *p1 = new int;cout << *p1 << endl;//在堆区申请了int类型大小的空间并初始化,然后将地址赋值给p1int *p2 = new int(100);cout << *p2 << endl;
连续申请
//在堆区连续申请了5个int类型大小的空间,并将地址赋值给p1int *p1 = new int[5];for(int i=0;i<5;i++){cin >> p1[i];}for(int j=0;j<5;j++){cout << p1[j] << " ";}cout << endl;
内存回收(释放)
单个回收
格式:delete 指针名;
delete p1;
例:
//在堆区申请了int类型大小的空间并初始化,然后将地址赋值给p1int *p2 = new int(100);cout << *p2 << endl;delete p2;p2 = nullptr; //p2 = NULL;
连续回收
格式:delete []指针名;
delete []p2;
例:
//在堆区连续申请了5个int类型大小的空间,并将地址赋值给p1int *p1 = new int[5];for(int i=0;i<5;i++){cin >> p1[i];}for(int j=0;j<5;j++){cout << p1[j] << " ";}cout << endl;delete []p1;p1 = nullptr; //p1 = NULL
new,delete和malloc,free的区别(面试重点)
new,delete
- 是关键字
- 申请空间以数据类型为单位
- 申请堆区空间是时可以初始化
- 申请什么类型的空间,指针就是什么类型
- 区分单个,连续的格式
- 申请对象空间时,会自动调用构造函数
- delete释放类对象空间时,会自动调用析构函数
malloc,free
- 是函数
- 申请空间以字节为单位
- 申请堆区空间时不能初始化
- 申请空间需要强转
- 不区分单个,连续的格式
- 申请对象空间时,不会自动调用构造函数
- free释放类对象空间时,不会自动调用析构函数
类中的特殊的成员函数
特殊的成员函数的种类:构造函数,析构函数,拷贝构造函数,拷贝赋值函数,移动构造,移动赋值,取地址符重载,常取地址符重载
特殊原因:
- 这些函数无需程序员手动定义,系统会默认提供,如果程序员手动调用,那么系统就取消提供。
- 这些函数无需手动调用,在特定的情况下会自动调用,即使是程序员手动定义的函数
构造函数
功能:
用类对象实例化一个对象时,会自动调用构造函数,给该对象申请空间和初始化使用的
格式:
函数名:与类同名
返回值:无,也无void
参数:可以有参数,可以无参数
访问权限:一般为public
类名(形参列表)
{函数体内容;
}
调用时机:
栈区
何时实例化对象,何时自动调用构造函
堆区
何时用new申请对象空间,合适自动调用构造函数
#include <iostream>using namespace std;class Student
{
private:string name;int age;string id;
public:void show(){cout << "名字: " << name << " 年纪:" << age << " 学号:" << id << endl;}//无参构造函数Student(){cout << "Student::无参构造函数" << endl;}//有参构造函数Student(string name,int age,string id){this->name = name;this->age = age;this->id = id;cout << "Student::有参构造函数" << endl;}
};int main()
{Student s1("zhang",10,"20200106133");s1.show();return 0;
}
系统默认提供的是无参构造函数,如果程序员手动定义,则系统取消默认提供,如果后期需要用到无参构造函数,则必须显性定义出来,否则报错。
可以给有参构造函数赋初始值。
初始化列表
构造函数的本身工作是完成类对象申请空间的,而初始化工作由初始化列表完成。
初始化列表由构造函数的形参小括号后由冒号引出
类名(形参1,形参2,形参3,...,形参n):成员变量1(形参1),成员变量2(形参2),成员变量3(形参3),..,成员变量n(形参n)
{函数体内容
}
#include <iostream>using namespace std;class Student
{
private:string name;int age;string id;
public:void show(){cout << "名字: " << name << " 年纪:" << age << " 学号:" << id << endl;}//无参构造函数Student(){cout << "Student::无参构造函数" << endl;}//有参构造函数Student(string name,int age,string id):name(name),age(age),id(id){cout << "Student::有参构造函数" << endl;}
};int main()
{Student s1("zhang",10,"20200106133");s1.show();return 0;
}
类的嵌套
#include <iostream>using namespace std;class Birthday
{
private:int year;int month;int day;
public://无参构造函数Birthday(){cout << "Birethday::无参构造函数" << endl;}//有参构造函数Birthday(int year,int month,int day):year(year),month(month),day(day){cout << "Birthday::有参构造函数" << endl;}
};class Student
{
private:string name;int age;Birthday b;
public://无参构造函数Student(){cout << "Student::无参构造函数" << endl;}//有参构造函数Student(string name,int age,int year,int month,int day):name(name),age(age),b(year,month,day){cout << "Student::有参构造函数" << endl;}};int main()
{Student s1("zhang",24,2002,12,05);return 0;
}
析构函数
功能:
当类对象的生命周期结束后,会自动调用析构函数,来完成类对象的资源回收。
格式:
函数名:~类名
返回值:无返回值,也无void
参数:无参数
调用时机:
栈区:
类对象所在的函数结束,会自动调用析构函数
先构造的对象后析构(栈区先进后出)
堆区:
何时使用delete,何时自动调用析构函数
#include <iostream>using namespace std;class Cat
{
private:string name;string color;
public://无参构造函数Cat(){cout << "Cat::无参构造函数" << endl;}//有参构造函数Cat(string n,string c):name(n),color(c){cout << "Cat::有参构造函数" << endl;}//析构函数~Cat(){cout << "Cat::析构函数" << endl;}
};int main()
{Cat c1("zhang","black");Cat c2;return 0;
}
系统会默认提供一个析构函数,如果程序员手动定义,则系统取消默认提供
每个类中只能由一个析构函数。(原因:析构函数无参,不能重载)
当类中有指针成员时,并且该指针成员指向了堆区空间,此时需要将系统提供的析构函数显性定义出来,在析构函数中手动将指针成员申请的堆区空间释放,否则会导致内存泄漏
拷贝构造函数
功能:
拷贝构造函数是一种特殊的构造函数,用一个类对象给另一个类对象初始化使用的
格式:
函数名:类名
返回值:无返回值,无void
参数:同类的类对象
访问权限:一般为public
类名(const 类名 &other)
{函数体内容;
}
调用时机:
- 用一个类对象给另一个类对象初始化使用的,自动调用拷贝构造函数
- 当类对象作为函数的实参传递给形参的过程,自动调用拷贝构造函数
- 当函数返回一个类对象的时,会自动调用拷贝构造函数
浅拷贝和深拷贝(重点)
系统会默认提供一个拷贝构造函数,如果程序员手动定义,则系统取消默认提供。
系统提供的拷贝构造函数,是将一个对象的所有数据成员初始化另一个对象的所有数据成员,称为浅拷贝。
练习
设计一个Per类,类中包含私有成员:姓名、年龄、指针成员身高、体重,再设计一个Stu类,类中包含私有成员:成绩、Per类对象p1,设计这两个类的构造函数、析构函数和拷贝构造函数。
#include <iostream>using namespace std;class Par
{
private:string name;int age;int *height;int *weight;
public://无参构造函数Par(){cout << "Par::无参构造函数" << endl;}//有参构造函数Par(string n,int a,int h,int w):name(n),age(a),height(new int(h)),weight(new int(w)){cout << "Par::有参构造函数" << endl;}//析构函数~Par(){cout << "Par::析构函数" << endl;}//拷贝构造函数Par(const Par &other):name(other.name),age(other.age),height(new int(*(other.height))),weight(new int(*(other.weight))){cout << "Par:拷贝构造函数" << endl;}
};class Stu
{
private:int score;Par p1;
public://无参构造函数Stu(){cout << "Stu::无参构造函数" << endl;}//有参构造函数Stu(int s,string n,int a,int h,int w):score(s),p1(n,a,h,w){cout << "Stu::有参构造函数" << endl;}//析构函数~Stu(){cout << "Stu::析构函数" << endl;}//拷贝构造函数Stu(const Stu &other):score(other.score),p1(other.p1){cout << "Stu:拷贝构造函数" << endl;}};int main()
{Par p0;Par p("zhang",24,64,180);Par p1 = p;Stu s0;Stu s(98,"zhang",24,64,180);Stu s1 = s;return 0;
}
这篇关于C++中类的相关学习的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!