当前位置: 首页 > news >正文

C++中类和动态内存分配

new关键字

在C++中,内存分为栈和堆。栈中的对象生命周期较短,往往在作用域结束后就会销毁,而堆中的对象生命周期较长,只有当使用delete或者程序结束时才会销毁。而new则是将我们创建的对象分配到堆中,使对象可以跨作用域使用。

类成员

部分引用类型的类成员就会用到new,例如String中的char*指针,这样类就可以处理不同长度的字符串,而不是在类设计时固定一个数组的长度,但是在类构造中使用new一定要记得释放和同步,如果构造函数中使用new则在析构函数用要使用delete。

String::String(){ stp = new char[length + 1];}

String::~String(){ delete stp; stp = NULL;}

 

类的赋值运算符和复制构造函数

这个还挺重要的,因为在C++中不使用new也可以创建类对象,但是是分配在栈中的,这样在使用指针的时候就会出现一些问题。

String function(String stp){

String myString;  //隐式调用默认构造函数在栈中创建一个myString对象 

stp = myString;

return stp;

}    //当该作用域结束时,该对象会被销毁,而其也会相应的调用其析构函数

在上述例子中,我们是可以获得一个返回的String对象的,但是当调用其中的指针读取字符时则会出现问题,首先:

1.当需要赋值时会创建一个临时变量,然后调用复制构造函数将myString对象中的成员对象复制到临时变量中。

2.在使用复制构造函数时,只会简单的进行浅拷贝,对于基本类型是值拷贝,而引用类型则是地址的拷贝。

3.赋值运算符还是会进行一次对象的赋值,所以还需要重写赋值运算符,因为不清楚程序是否会调用还是保险为好。

当使用stp = myString;时

可能会用到复制构造函数,也可能用到赋值运算符,在这种情况下可以使用两者都进行重写。

重写复制构造函数:

Class_name(const Class_name&);

重写赋值运算符:

Class_name& Class_name::operator=(cosnt Class_name&);

例子:

String(const String& str){

        delete[] this->stp;

        this->stp = new char[length + 1];

        for(int i = 0; i < size;i++){

                        this->stp[i] = str.stp[i];

        }

}

使用上述构造函数和赋值运算的重写,将类对象中的引用类型进行值的拷贝,这样当赋值时临时对象的销毁就不会引起空指针或者内存泄漏的问题。

成员初始化列表

 C++构造函数提供了一种可以用来初始化数据成员的特殊语法,就是使用成员初始化列表。

语法:

String::String(int qs):qSize(qs),items(0),front(NULL),real(NULL){

                        

}

这种方式可以初始化非静态的const对象。

或者直接在类中定义初始化

class String{

        private:

        enum{Q_SIZE = 10};

        Node* front = NULL;

        int items = 0;

        const int qSize = Q_SIZE;

}

 

自动应用类型转换

 将一个标准类型变量赋给另一种标准类型变量时,如果两者类型兼容,则C++自动将这个值转换为接收变量的类型。

只接受一个参的构造函数才能作为转换函数。

String(double db);

String(int i);

String(char a);

当声明以上构造函数时,使用下面方式会进行隐式的调用对应的构造函数,将其他类型转为String类型对象.

String a = 1;  //调用形参为int的构造函数

String b = 23.2;  //double 

function(String str);

function(1);  //也会转换为String对象

但是这样会产生一部分问题,当并不想隐式的执行转换函数时,需要使用explicit关键字来关闭这种自动特性。

explicit String(int i);  //不能隐式的作为转换。 

String a = 1  //错误,不能使用隐式转换

String a = (String)1;  //正确

String a = String(1);  //正确

类构造器也支持自动转换,允许可以转型的对象进行自动的转换.

例如,只持有一个double型参的构造函数:

 String(double db);

String a = 1;  //将int类型转换为double类型然后创建对象。

但是自动转换不能有二义性,如果String构造函数中还存在其他可以由int转型的类型如long,则会出现错误,编译器将提示错误。

转换函数

 既然可以将其他类型转换为类对象,也可以将类对象转换为特定的一种类型,需要使用到转换函数。

需要注意的是:

1.转换函数为类方法

2.不允许有返回类型

3.不能有型参

语法:

operator double();

例子:

explicit operator int(){  //使用explicit关键字,防止隐式转化

       int length = this->size;   

        int sumNum = 0;

        int dig = 1;

        for(int i = 0; i < length; i++){

                sumNum += (this->stp[i] - '0') * dig;

                dig *= 10;           

        }     

        return sumNum;

}

在上述例子中,将字符数组中的数字进行计算,得出了一个int值,实现了将String对象转换为int类型。 

相关文章:

  • linux硬盘扩容
  • 十六、RabbitMQ快速入门
  • 开源更安全? yum源配置/rpm 什么是SSH?
  • Vue 2.0中引入的类型检查Flow
  • TypeError: expected np.ndarray (got Tensor)解决办法
  • 【机器学习基础】对数几率回归(logistic回归)
  • elementplus DateTimePicker 日期范围选择器 设置默认时间范围为当前月的起始时间到结束时间
  • pytorch下载离线包的网址
  • 设置指定时间之前的时间不可选
  • kubernetes测试部署一个nginx
  • 【自学记录】深度学习进阶:自然语言处理(第一章 神经网络的复习)
  • Linux 启动停止重启jar包shell脚本
  • 【2023云栖】陈守元:阿里云开源大数据产品年度发布
  • 【数据库】你听说过矢量数据库吗?
  • 机器学习算法——集成学习
  • 分享的文章《人生如棋》
  • 【EOS】Cleos基础
  • JAVA_NIO系列——Channel和Buffer详解
  • JAVA多线程机制解析-volatilesynchronized
  • OSS Web直传 (文件图片)
  • Promise面试题2实现异步串行执行
  • sublime配置文件
  • vue-cli在webpack的配置文件探究
  • 基于Volley网络库实现加载多种网络图片(包括GIF动态图片、圆形图片、普通图片)...
  • 数据结构java版之冒泡排序及优化
  • 微信小程序:实现悬浮返回和分享按钮
  • 一、python与pycharm的安装
  • 一个项目push到多个远程Git仓库
  • 在GitHub多个账号上使用不同的SSH的配置方法
  • CMake 入门1/5:基于阿里云 ECS搭建体验环境
  • ​DB-Engines 12月数据库排名: PostgreSQL有望获得「2020年度数据库」荣誉?
  • ​html.parser --- 简单的 HTML 和 XHTML 解析器​
  • ​学习一下,什么是预包装食品?​
  • # centos7下FFmpeg环境部署记录
  • (AngularJS)Angular 控制器之间通信初探
  • (pojstep1.1.2)2654(直叙式模拟)
  • (附源码)spring boot网络空间安全实验教学示范中心网站 毕业设计 111454
  • (免费分享)基于springboot,vue疗养中心管理系统
  • (全注解开发)学习Spring-MVC的第三天
  • (十八)三元表达式和列表解析
  • (转)关于pipe()的详细解析
  • (转)淘淘商城系列——使用Spring来管理Redis单机版和集群版
  • .Family_物联网
  • .NET Conf 2023 回顾 – 庆祝社区、创新和 .NET 8 的发布
  • .net core 6 集成 elasticsearch 并 使用分词器
  • .net core 控制台应用程序读取配置文件app.config
  • .NET Core工程编译事件$(TargetDir)变量为空引发的思考
  • .NET/C# 编译期能确定的字符串会在字符串暂存池中不会被 GC 垃圾回收掉
  • .NET和.COM和.CN域名区别
  • @test注解_Spring 自定义注解你了解过吗?
  • []利用定点式具实现:文件读取,完成不同进制之间的
  • [AIR] NativeExtension在IOS下的开发实例 --- IOS项目的创建 (一)
  • [Angular] 笔记 7:模块
  • [BZOJ3757] 苹果树
  • [C/C++] C/C++中数字与字符串之间的转换