C++语法详解之封装、构造函数、析构函数

 更新时间:2020年03月07日 10:15:51   投稿:mrr  
这篇文章主要介绍了C++语法详解之封装、构造函数、析构函数的相关知识,通过实例代码给大家详细介绍,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下

大家先了解下什么是构造函数,什么是析构函数,作用是什么?

构造函数(方法)是对象创建完成后第一个被对象自动调用的方法。它存在于每个声明的类中,是一个特殊的成员方法。作用是执行一些初始化的任务。Php中使用__construct()声明构造方法,并且只能声明一个。

析构函数(方法)作用和构造方法正好相反,是对象被销毁之前最后一个被对象自动调用的方法。是PHP5中新添加的内容作用是用于实现在销毁一个对象之前执行一些特定的操作,诸如关闭文件和释放内存等。

下面在通过具体例子看下C++语法详解之封装、构造函数、析构函数。

成员变量私有化,提供公共的getter和setter给外界去访问成员变量

class Person {
 int age;
 
public:
 void setAge(int age){
  this->age = age;
 }
 
 int getAge(){
  return this->age;
 }
 
};

int main(){
 Person person;
 person.setAge(10);
 cout << person.getAge() << endl;
}

堆空间

在程序运行过程,为了能够自由控制内存的生命周期、大小,会经常使用堆空间的内存

堆空间的申请\释放

malloc \ free
new \ delete
new [] \ delete []

注意

  • 申请堆空间成功后,会返回那一段内存空间的地址
  • 申请和释放必须是1对1的关系,不然可能会存在内存泄露

现在的很多高级编程语言不需要开发人员去管理内存(比如Java),屏蔽了很多内存细节,利弊同时存在

  • 利:提高开发效率,避免内存使用不当或泄露
  • 弊:不利于开发人员了解本质,永远停留在API调用和表层语法糖,对性能优化无从下手

例如开盘int类型的空间,使用完之后销毁

int *p = (int *)malloc(sizeof(int));
 *p = 10;
 free(p);
 
 int *p2 = new int;
 *p2 = 20;
 delete p2;
 
 int *p3 = new int[3];
 *p = 10;
 *(p+1) = 20;
 *(p+2) = 30;
 delete [] (p3);

堆空间的初始化

memset

memset 函数是将较大的数据结构(比如对象、数组等)内存清零的比较快的方法

如下所示

 Person person;
 person.age = 10;
 person.height = 199;
 //从person的地址开始,每个字节都赋值为0
memset(&person, 0, sizeof(person));

初始化

int *p1 = (int *)malloc(sizeof(int)); //*p1 未初始化
int *p2 = (int *)malloc(sizeof(int));
memset(p2, 0, sizeof(int));//将 *p2 的每一个字节都初始化为0

如下几种方式

int *p1 = new int;   //未初始化
int *p2 = new int();   //被初始化为0
int *p3 = new int(5);  //被初始化为5
int *p4 = new int[3];  //数组元素未被初始化
int *p5 = new int[3]();  //3个数组元素都被初始化0
int *p6 = new int[3]{};  //3个数组元素都被初始化0
int *p7 = new int[3]{5};  //数组首元素被初始化为5,其他元素被初始化为0

构造函数(Constructor)

构造函数(也叫构造器),在对象创建的时候自动调用,一般用于完成对象的初始化工作

特点

  • 函数名与类同名,无返回值(void都不能写),可以有参数,可以重载,可以有多个构造函数
  • 一旦自定义了构造函数,必须用其中一个自定义的构造函数来初始化对象

注意

通过malloc分配的对象不会调用构造函数
一个广为流传的、很多教程\书籍都推崇的错误结论:
默认情况下,编译器会为每一个类生成空的无参的构造函数
正确理解:在某些特定的情况下,编译器才会为类生成空的无参的构造函数
比如我们自己写2个构造函数

class Person{
public:
 int age;
 
 Person(){
  cout << "Person()" << endl;
 }
 
 Person(int age){
   cout << "Person(int age))" << endl;
 }
};

在不同的空间调用的时候,如下区别

// 全局区
Person p1;  //调用Person()
Person p2(); //这是一个函数,函数名是p2,返回值类型是Person,无参
Person p3(18); //调用 Person(int)

int main(){
 //栈空间
 Person p4;  //调用Person()
 Person p5(); //这是一个函数,函数名是p5,返回值类型是Person,无参
 Person p6(18); //调用 Person(int)
 
 
 //堆空间
 Person *p7 = new Person;  //调用Person()
 Person *p8 = new Person(); //调用Person()
 Person *p9 = new Person(20); //调用 Person(int)
}

析构函数

析构函数(也叫析构器),在对象销毁的时候自动调用,一般用于完成对象的清理工作

特点

函数名以~开头,与类同名,无返回值(void都不能写),无参,不可以重载,有且只有一个析构函数

注意

  • 通过malloc分配的对象free的时候不会调用析构函数
  • 构造函数、析构函数要声明为public,才能被外界正常使用

例如下面的代码

class Cat{
public:
 int age;
 Cat(){
  cout << "Cat()" << endl;
 }
 
 ~Cat(){
  cout << "~Cat()" << endl;
 }
};


class Person{
public:
 int age;
 Cat *cat;
 Person(){
  this->cat = new Cat();
  cout << "Person()" << endl;
 }
 
 ~Person(){
  cout << "~Person()" << endl;
 }
};

int main(){
 {
  Person person;
 }
 return 0;
}

输出

Cat()
Person()
~Person()

当person销毁的时候,其持有的cat并没有销毁。

原因

当person销毁的时候,其指向cat对象的指针销毁了,但是堆空间的cat对象依然存在,就会有内存泄露。所以需要在析构函数里面来释放掉。类似的析构函数在许多其他语言底层也是应用广泛,例如Objective-C的源码中,大量使用析构函数。

代码改成如下所示:

~Person(){
  delete cat;
  cout << "~Person()" << endl;
 }

输出

Cat()
Person()
~Cat()
~Person()

可知,cat对象才真正销毁。

总结

到此这篇关于C++语法详解之封装、构造函数、析构函数的文章就介绍到这了,更多相关c++ 封装构造函数析构函数内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • C语言malloc分配问题详解

    C语言malloc分配问题详解

    这篇文章主要介绍了c语言 malloc函数的分配问题,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-09-09
  • C语言解数独程序的源码

    C语言解数独程序的源码

    这篇文章主要为大家详细介绍了C语言解数独程序的源码,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-01-01
  • C语言实现数独游戏

    C语言实现数独游戏

    这篇文章主要为大家详细介绍了C语言实现数独游戏,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2022-03-03
  • VC基于ADO技术访问数据库的方法

    VC基于ADO技术访问数据库的方法

    这篇文章主要介绍了VC基于ADO技术访问数据库的方法,较为详细的分析了VC使用ADO操作数据库的相关实现技巧,具有一定参考借鉴价值,需要的朋友可以参考下
    2015-10-10
  • 冒泡算法的改进具体实现

    冒泡算法的改进具体实现

    这篇文章主要介绍了冒泡算法的改进具体实现,有需要的朋友可以参考一下
    2013-12-12
  • C/C++函数调用的几种方式总结

    C/C++函数调用的几种方式总结

    本篇文章主要是对C/C++函数调用的几种方式进行了详细的总结介绍,需要的朋友可以过来参考下,希望对大家有所帮助
    2013-12-12
  • C语言判断一个数是否是2的幂次方或4的幂次方

    C语言判断一个数是否是2的幂次方或4的幂次方

    本文中我们来看一下如何用C语言判断一个数是否是2的幂次方或4的幂次方的方法,并且判断出来是多少次方,需要的朋友可以参考下
    2016-06-06
  • OpenCV+Qt实现图像处理操作工具的示例代码

    OpenCV+Qt实现图像处理操作工具的示例代码

    这篇文章主要介绍了利用OpenCV+Qt实现图像处理操作工具,可以实现雪花屏、高斯模糊、中值滤波、毛玻璃等操作,感兴趣的可以了解一下
    2022-08-08
  • C++11新特性之四种类型转换cast说明

    C++11新特性之四种类型转换cast说明

    类型转换是项目中常使用的一种语法规则,几乎每个编程语言都不可避免的涉及到这方面,下面这篇文章主要给大家介绍了关于C++11新特性之四种类型转换cast说明的相关资料,需要的朋友可以参考下
    2023-02-02
  • C语言中qsort函数用法实例小结

    C语言中qsort函数用法实例小结

    这篇文章主要介绍了C语言中qsort函数用法,包括了针对各种数据类型参数的排序,非常具有实用价值,需要的朋友可以参考下
    2014-09-09

最新评论