【C++学习笔记 19】C++中的对象生存周期

2024-09-05 07:04

本文主要是介绍【C++学习笔记 19】C++中的对象生存周期,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

对象如何生存在栈上

在C++中,我们每次进入一个作用域时,我们就是在push栈帧。就像把书堆叠起来,将最新的书放在最上层,在这个作用域上创建变量就像在书中写内容,当作用域结束的时候,就把书拿走,此时每个基于栈的变量就结束了。

举个例子

#include <iostream>
#include <string>class Entity
{
public:Entity(){std::cout << "Created Entity!" << std::endl;}~Entity(){std::cout << "Destroyed Entity" << std::endl;}
};int main() {{Entity e;}std::cin.get();
}

创建一个包含构造函数与析构函数的类,并在一个作用域中创建它,将创建类的实例的语句打上断点,步进。会发现在离开作用域时,就会触发析构函数,表明实例被销毁了,这就是在栈上创建变量。

{Entity* e = new Entity();
}

如果将作用域中的语句改为上述,再次debug步进,会发现直到程序结束,析构函数都没有被触发。
这直观体现了在 栈和堆上创建变量的特点。

如何使用

一个典型的错误案例

int* CreateArray() {int array[50];return array;
}

上述函数乍一看似乎没有什么问题,细看却发现,其返回的是局部变量的指针,当函数运行完毕,栈上的内存空间被回收,指针的对象不再是定义的数组。
如果要实现这样的目的,可以将数组创建在堆上,也可以把这里创建的数组赋值给一个在这个作用域外的变量。

class ScopedPtr
{
private:Entity* m_ptr;
public:ScopedPtr(Entity* ptr): m_ptr(ptr){}~ScopedPtr() {delete m_ptr;}
};

如果想在离开作用域时自动删除堆上创建的变量,可以采用上述的类,一个简单的作用域指针。

{ScopedPtr e(new Entity());
}

并使用它创建实例,由于ScopedPtr的实例是在栈上创建的,因此在离开作用域时会销毁,而此时会调用析构函数,从而删除Entity的指针。这实现了smart ptrunique ptr的基本功能。
这种在离开作用域时指针被销毁的功能很有用,比如说可以做一个作用域的计时器,在离开时自动停止计时。或者可以写一个自动的作用域锁,在函数开始时锁定它,然后在结束时解锁。


教程来源:The Cherno C++ 教程

这篇关于【C++学习笔记 19】C++中的对象生存周期的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1138278

相关文章

golang 对象池sync.Pool的实现

《golang对象池sync.Pool的实现》:本文主要介绍golang对象池sync.Pool的实现,用于缓存和复用临时对象,以减少内存分配和垃圾回收的压力,下面就来介绍一下,感兴趣的可以了解... 目录sync.Pool的用法原理sync.Pool 的使用示例sync.Pool 的使用场景注意sync.

C++ HTTP框架推荐(特点及优势)

《C++HTTP框架推荐(特点及优势)》:本文主要介绍C++HTTP框架推荐的相关资料,本文通过实例代码给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友参考下吧... 目录1. Crow2. Drogon3. Pistache4. cpp-httplib5. Beast (Boos

SpringBoot项目中Redis存储Session对象序列化处理

《SpringBoot项目中Redis存储Session对象序列化处理》在SpringBoot项目中使用Redis存储Session时,对象的序列化和反序列化是关键步骤,下面我们就来讲讲如何在Spri... 目录一、为什么需要序列化处理二、Spring Boot 集成 Redis 存储 Session2.1

Java实例化对象的​7种方式详解

《Java实例化对象的​7种方式详解》在Java中,实例化对象的方式有多种,具体取决于场景需求和设计模式,本文整理了7种常用的方法,文中的示例代码讲解详细,有需要的可以了解下... 目录1. ​new 关键字(直接构造)​2. ​反射(Reflection)​​3. ​克隆(Clone)​​4. ​反序列化

重新对Java的类加载器的学习方式

《重新对Java的类加载器的学习方式》:本文主要介绍重新对Java的类加载器的学习方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、介绍1.1、简介1.2、符号引用和直接引用1、符号引用2、直接引用3、符号转直接的过程2、加载流程3、类加载的分类3.1、显示

Pandas进行周期与时间戳转换的方法

《Pandas进行周期与时间戳转换的方法》本教程将深入讲解如何在pandas中使用to_period()和to_timestamp()方法,完成时间戳与周期之间的转换,并结合实际应用场景展示这些方法的... 目录to_period() 时间戳转周期基本操作应用示例to_timestamp() 周期转时间戳基

C++类和对象之初始化列表的使用方式

《C++类和对象之初始化列表的使用方式》:本文主要介绍C++类和对象之初始化列表的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录C++初始化列表详解:性能优化与正确实践什么是初始化列表?初始化列表的三大核心作用1. 性能优化:避免不必要的赋值操作2. 强

C++迭代器失效的避坑指南

《C++迭代器失效的避坑指南》在C++中,迭代器(iterator)是一种类似指针的对象,用于遍历STL容器(如vector、list、map等),迭代器失效是指在对容器进行某些操作后... 目录1. 什么是迭代器失效?2. 哪些操作会导致迭代器失效?2.1 vector 的插入操作(push_back,

C#如何调用C++库

《C#如何调用C++库》:本文主要介绍C#如何调用C++库方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录方法一:使用P/Invoke1. 导出C++函数2. 定义P/Invoke签名3. 调用C++函数方法二:使用C++/CLI作为桥接1. 创建C++/CL

Java学习手册之Filter和Listener使用方法

《Java学习手册之Filter和Listener使用方法》:本文主要介绍Java学习手册之Filter和Listener使用方法的相关资料,Filter是一种拦截器,可以在请求到达Servl... 目录一、Filter(过滤器)1. Filter 的工作原理2. Filter 的配置与使用二、Listen