c++基础2

一、c++的引用   引用和指针的的区别?

        引用是一种更安全的指针:

                1. 引用必须初始化,指针可以不用初始化
int a =10;
int *p; // 指针可能是野指针
int &b =a;//引用赋值",通常指的是直接修改引用所引用的对象的值,而不需要显式解引用。如果你在说 "指针赋值",通常需要通过解引用操作来修改指针所指向的对象的值。
                2. 引用只有一级引用,没有多级引用, 指针有一级,也有多级
int a =10;
int * p = &a;  // *p=30 需要手动解引用
int &b = a;   // 在底层 b =20; 的时候,会自动解引用
                3.  定义一个引用变量和 定义一个指针变量,其汇编指令是一样的; 通过引用变量修改所引用内存的值,和通过指针解引用修改指针指向内存的值,其底层指令也是一样的。
// 引用一个数组
int array[5] ={};
int (&q)[5] = array;

二、左值引用和右值引用 

        右值引用主要用于绑定到右值(右值是指表达式结束后不再存在的临时对象,比如字面量、临时表达式的结果等)。 

         左值引用和右值引用的引入是为了支持移动语义和避免不必要的拷贝操作,特别是在处理临时对象和资源管理时。右值引用可以绑定到临时对象,并通过移动语义实现高效的资源管理。左值引用则绑定到持久存在的对象,用于常规的引用传递和修改对象的操作。 C++11 引入了右值引用,C++14 进一步完善了右值引用的特性。

右值引用的本质主要体现在以下几个方面:

  1. 允许绑定到临时对象: 右值引用允许绑定到即将被销毁的临时对象,从而允许我们获取和操作这些临时对象的内容。

  2. 支持移动语义: 通过右值引用,可以实现移动语义。移动语义是一种在对象之间转移资源所有权的机制,可以避免不必要的拷贝操作,提高性能。

  3. 在重载函数中的应用: 右值引用广泛用于重载移动构造函数和移动赋值运算符,以实现高效的对象移动

  4. class MyString {
    public:// 移动构造函数MyString(MyString&& other) noexcept : data(other.data), size(other.size) {other.data = nullptr;other.size = 0;}// 移动赋值运算符MyString& operator=(MyString&& other) noexcept {if (this != &other) {delete[] data;data = other.data;size = other.size;other.data = nullptr;other.size = 0;}return *this;}private:char* data;std::size_t size;
    };
    

           上述代码中,MyString 类实现了移动构造函数和移动赋值运算符,通过右值引用,可以高效地进行对象的资源移动。

           总体而言,右值引用的本质是一种引用类型,其设计目的是为了支持移动语义和更高效的资源管理。通过右值引用,程序员可以更精准地控制对象的生命周期和资源的传递,以提高代码的性能和效率。

    三、 delete 和free区别是是吗?  new和malloc区别是什么?  

newmalloc 都是在 C++ 中用于动态分配内存的操作符,但它们有一些重要的区别:

  1. 语法:

    • new new 是 C++ 中的关键字,使用时直接调用,并返回指定类型的指针。
      int* p = new int;
    • malloc malloc 是 C 语言中的库函数,返回 void* 类型的指针。在 C++ 中可以使用,但通常搭配 reinterpret_cast 来进行类型转换。
      int* p = reinterpret_cast<int*>(malloc(sizeof(int)));
  2. 类型安全:

    • new new 是类型安全的,它会自动计算所需的内存大小,并返回指定类型的指针。它还调用了对象的构造函数,对于自定义类型来说更加方便。
    • malloc malloc 返回的是 void*,需要手动计算所需的内存大小,并且不会调用对象的构造函数。在 C++ 中,使用 malloc 分配内存后,需要使用 placement new 构造对象。
  3. 构造与析构:

    • new new 会调用对象的构造函数,创建一个完全初始化的对象。当使用 delete 释放内存时,会调用对象的析构函数。
    • malloc malloc 不会调用对象的构造函数和析构函数,需要手动管理对象的生命周期。
  4. 操作符重载:

    • new 可以通过重载 newdelete 操作符来自定义内存分配和释放行为。
    • malloc mallocfree 是标准库函数,不能被重载。
  5. 异常处理:

    • new 如果分配失败,会抛出 std::bad_alloc 异常,可以通过 nothrow 参数禁止抛出异常。
    • malloc 如果分配失败,返回 nullptr,不抛出异常。需要手动检查返回值。

在 C++ 中,推荐使用 newdelete,因为它们更加类型安全,对对象的构造和析构进行了正确处理。使用 mallocfree 主要是在一些特殊情况下,或者与 C 语言代码交互的场景中。在现代 C++ 中,智能指针和容器类的使用也减少了手动内存管理的需求

三、 面向对象

面向对象思想(详解)-CSDN博客

        面向对象是一种编程的思想,对象在栈上

类内实现的方法会自动展开为内联函数

类外实现的方法

对象的大小通过成员变量计算

#include <iostream>class MyClass {
public:int x;  // 4 byteschar c; // 1 bytedouble d; // 8 bytes// ConstructorMyClass(int a, char b, double e) : x(a), c(b), d(e) {}
};int main() {std::cout << "Size of MyClass: " << sizeof(MyClass) << " bytes" << std::endl;return 0;
}

this 是一个指向当前对象的指针,它是类成员函数中的一个隐含参数。this 指针提供了对调用对象的访问,使得在类的成员函数中可以访问到当前对象的成员变量和其他成员函数。 

 每个对象都有自己的成员变量,但是他们共享一套成员方法。(那怎么区分哪个对象调用成员变量)

类的成员方法一经编译,所有的方法参数,都会加一个this指针,接受调用该方法的对象地址。this会告诉编译器处理哪个对象的方法。

以下是关于 this 指针的一些重要事项:

  1. 隐含参数: 在类的成员函数中,编译器会隐含地将当前对象的地址作为第一个参数传递给成员函数,而这个参数就是 this 指针。

  2. 使用 this 指针: 可以使用 this 指针访问对象的成员。例如,在成员函数中访问成员变量时,可以省略 this->,因为编译器会自动识别并添加。

    class MyClass {
    public:int x;void setX(int value) {this->x = value; // 可以省略this->,直接写成x = value}
    };
    
  3. 返回 this 指针: 在成员函数中,可以返回 this 指针,以支持链式调用(chaining)。使用链式调用可以写成:obj.setX(42).doSomething();

  4. class MyClass {
    public:int x;MyClass& setX(int value) {this->x = value;return *this;}
    };
    
  5. 在静态成员函数中不存在: 静态成员函数是与类关联而不是与对象关联的,因此在静态成员函数中不存在 this 指针。

    class MyClass {
    public:static void staticFunction() {// 在静态成员函数中无法使用this指针}
    };
    

this 指针在编写成员函数时非常有用,它使得成员函数能够访问对象的成员变量和其他成员函数。通过 this 指针,可以在类的成员函数中明确指出当前对象,从而正确地访问成员。

四、构造函数和析构函数

构造函数和析构函数的函数名字和类名一样,切没有返回值。

1 . 开辟内存(在栈上为对象开辟内存)

2. 调用构造函数(初始化,可以有参数,可以提供多个构造函数,叫做构造函数的重载)

...

n. 出作用域的时候,在return处对象依次会析构(先构造的晚析构,后构造的先析构, 类只能有一个析构函数,析构可以自己调用s1.~seq();,释放对象成员变量占用的外部堆内存, 析构函数调用以后,我们就说对象没有了,但是对象在栈上,只要函数存在对象就在,但是别去调用对象的方法,有可能造成堆的内存非法访问)

可以在三个地方创建对象:

栈(Stack)进入函数时构造

        
 深拷贝:

        在赋值时,把s2的new的内存直接丢了,而指向s1的。这时候需要做=运算符重载  s2.operator=(s1);

        深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象,是“值”而不是“引用”(不是分支)

        拷贝第一层级的对象属性或数组元素

        递归拷贝所有层级的对象属性和数组元素

        深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。

  • 栈是一种后进先出(LIFO)的数据结构,用于存储函数调用和局部变量。
  • 对象在栈上分配的时候,它的生命周期与所在函数的生命周期相同,当函数执行完成时,对象自动被销毁。
  • 对象的大小通常较小,因为栈的大小是有限制的,过大的对象可能会导致栈溢出。
  • 通过在栈上分配对象,可以实现高效的内存管理,但是对象的生命周期受限于函数的执行。
    #include <iostream>class MyClass {
    public:MyClass(int val) : value(val) {std::cout << "Constructor called. Value: " << value << std::endl;}~MyClass() {std::cout << "Destructor called. Value: " << value << std::endl;}void display() {std::cout << "Value: " << value << std::endl;}private:int value;
    };int main() {// 在栈上构建对象MyClass stackObject(10);stackObject.display();// 对象生命周期结束时,析构函数会被自动调用return 0;
    }
    

    堆(Heap) new的时候构造

  • 堆是一块用于动态分配内存的区域,对象在堆上分配时,它的生命周期由程序员负责管理。
  • 对象在堆上分配通常使用 new(C++)或 malloc(C)等操作符。
  • 使用堆分配内存可以实现灵活的对象生命周期,但需要手动释放分配的内存,以防止内存泄漏。
  • 堆上的对象可以在多个函数之间传递,因为它的生命周期不受限于单个函数
  • #include <iostream>class MyClass {
    public:MyClass(int val) : value(val) {std::cout << "Constructor called. Value: " << value << std::endl;}~MyClass() {std::cout << "Destructor called. Value: " << value << std::endl;}void display() {std::cout << "Value: " << value << std::endl;}private:int value;
    };int main() {// 在堆上构建对象MyClass* heapObject = new MyClass(20);heapObject->display();// 注意:需要手动释放堆上分配的对象delete heapObject;return 0;
    }
    

    对于new的对象,是在堆上建的,首先delete会调用对象的析构函数对象在堆上的成员变量进行释放,然后再释放对象内存

  • 数据段/静态存储区程序启动时构造函数

  • 数据段用于存储全局变量和静态变量,这些变量在程序运行的整个生命周期内都存在。
  • 对象在数据段上分配时,它的生命周期与程序的生命周期相同。
  • 数据段适合存储一些在程序运行期间始终存在的全局数据。
    #include <iostream>class MyClass {
    public:MyClass(int val) : value(val) {std::cout << "Constructor called. Value: " << value << std::endl;}~MyClass() {std::cout << "Destructor called. Value: " << value << std::endl;}void display() {std::cout << "Value: " << value << std::endl;}private:int value;
    };// 在数据段上定义全局对象
    MyClass globalObject(30);int main() {// 全局对象在整个程序生命周期内存在globalObject.display();return 0;
    }
    

  • 五、对象的深拷贝和浅拷贝

  •  浅拷贝

  • 浅拷贝只复制指向某个对象的指针,

    SeqStack s;
    SeqStack s1(10);
    SeqStack s2 =s1; // 默认拷贝构造函数 相当于 SeqStack s3(s1);   -》浅拷贝(内存拷贝)
    s2 =s1 ; 默认赋值函数  -》 浅拷贝(内存拷贝)
    点击并拖拽以移动
    memcpy和recalloc都是浅拷贝

    而不复制对象本身,新旧对象还是共享同一块内存(分支)

    浅拷贝是按位拷贝对象,它会创建一个新对象,这个对象有着原始对象属性值的一份精确拷贝。

    如果属性是基本类型,拷贝的就是基本类型的值;如果属性是内存地址(引用类型),拷贝的就是内存地址 ,因此如果其中一个对象改变了这个地址,就会影响到另一个对象。

   深拷贝:

        在赋值时,把s2的new的内存直接丢了,而指向s1的。这时候需要做=运算符重载  s2.operator=(s1);

        深拷贝会另外创造一个一模一样的对象,新对象跟原对象不共享内存,修改新对象不会改到原对象,是“值”而不是“引用”(不是分支)

        拷贝第一层级的对象属性或数组元素

        递归拷贝所有层级的对象属性和数组元素

        深拷贝会拷贝所有的属性,并拷贝属性指向的动态分配的内存。当对象和它所引用的对象一起拷贝时即发生深拷贝。深拷贝相比于浅拷贝速度较慢并且花销较大。

 

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt/QML编程之路:小键盘keyboard(36)

小键盘对于qml应用是经常用到的,在qml里面,就如一个fileDialog也要自己画一样,小键盘keyboard也是要自己画的,对于相应的每个按键的clicked都要一一实现的。 这里有一个示例: 代码如下: import QtQuick 2.5 import QtQuick.Controls 1.4 import QtQuick.Window 2.0 im…

yum仓库以及NFS共享

yum实现过程 1.光驱里自带yum 2.网络下载到本地 3.直接通过网络 如何实现安装服务 yum客户端找到yum服务端&#xff0c;找到yum的仓库位置&#xff0c;下载元信息&#xff0c;因为里面有软件的位置&#xff0c;因此可以找到软件包的位置&#xff0c;然后下载到本地 仓库的类…

25考研英语复习计划

Hello各位小伙伴大家好&#xff0c;今天要给大家分享的是英语备考计划&#xff0c;大家可以作为参考&#xff0c;制定适合自己的备考计划。 【英一/二】 英语分为英一、英二&#xff0c;一般学硕英一&#xff0c;专硕英二。 英一要比英二难度大。 【复习计划】 1-2月&#xf…

图深度网络浅层理解

图神经网络 1.输入&#xff1a; 图网络 2.输出&#xff1a; 节点类别、某两个节点的新连接、产生新的图或子图 3.端到端表示学习&#xff08;Representation Learning&#xff09;/图嵌入&#xff1a; 将节点映射为d维的向量&#xff0c;d维向量就包含了这个节点的连接关系…

H5小游戏如何提升APP变现收益?

在当前用户规模稳定但变现压力增加的背景下&#xff0c;开发者需要挖掘用户价值&#xff0c;提高营收&#xff0c;这成为开发者关注的重点话题。对于那些“用户用完即走”的APP产品来说&#xff0c;接入H5游戏能够吸引停留&#xff0c;为其带来收入上的增长。 一、什么是H5游戏…

小程序学习-17

attached最常用 推荐使用 lilfetimes 这种方法

springcloud Eureka服务注册与发现

文章目录 代码地址Eureka基础知识什么是服务治理什么是服务注册与发现 单机版eurekaServerIDEA生成eurekaServer端服务注册中心类似物业公司EurekaClient端cloud-provider-payment8001修改EurekaClient端cloud-consumer-order80 集群Eureka构建步骤新建cloud-eureka-server7002…

计算机找不到iutils.dll的5种有效的解决方法,一分钟教会修复dll问题

在计算机使用过程中&#xff0c;我们经常会遇到一些错误提示&#xff0c;其中最常见的就是“某某文件丢失”或“某某文件损坏”&#xff0c;找不到iutils.dll就是其中之一。iutils.dll是一个系统级的动态链接库文件&#xff08;DLL&#xff09;&#xff0c;它是Windows操作系统…

grep 在运维中的常用可选项

一、对比两个文件 vim -d <filename1> <filename2> 演示&#xff1a; 需求&#xff1a;&#xff5e;目录下有两个文件一个test.txt 以及 text2.txt,需求对比两个文件的内容。 执行后会显示如图&#xff0c;不同会高亮。 二、两次过滤 场景&#xff1a;当需要多…

(一)ROS的安装

&#xff08;一&#xff09;安装ubuntu18.04 系统&#xff08;虚拟机或者是物理机&#xff0c;在此不再介绍&#xff09; &#xff08;二&#xff09;添加ROS镜像源 apt 列表中没有ROS源&#xff0c;所以要手动添加 sudo sh -c . /etc/lsb-release && echo "deb…

在vite5和vue3开发环境中使用jodit4富文本编辑器,并添加自定义插件和使用highlight.js实现代码块高亮(附其他自定义配置项和全部代码)

最近富文本编辑器jodit终于更新发布到了4.0版本&#xff0c;加入了css变量、有更好的typescript支持&#xff0c;截止发文时的版本是&#xff1a;4.0.5&#xff0c;看到有了新版本于是便想着将本地项目中的jodit版本也进行升级&#xff0c;琢磨着再丰富和添加一些功能&#xff…

掌握Python 99 个实用实例,其中精选算法高频题目以及答案,助力求职Python工程师面试不慌拿offer

掌握Python 99 个实用实例&#xff0c;其中精选算法高频题目以及答案&#xff0c;助力求职Python工程师面试不慌拿offer。 Python由荷兰国家数学与计算机科学研究中心的吉多范罗苏姆于1990年代初设计&#xff0c;作为一门叫做ABC语言的替代品。Python提供了高效的高级数据结构&…

给机器人开发个功能让它帮我照看宝宝

本文首发于古月居 这篇博客主要讲述了如何通过OriginBot来看护宝宝&#xff0c;当宝宝的脸不在摄像头的范围之内时&#xff0c;发送消息到钉钉群组&#xff0c;通知家人及时查看。 前言 我在上个月有了宝宝&#xff0c;为了方便照看宝宝&#xff0c;就买了一个带有宝宝看护功能…

OpenLayers实战,OpenLayers点聚合有相同经纬度坐标时无法展开问题解决办法,当缩放级别达到一定等级后强行展开聚合为单个点

专栏目录: OpenLayers实战进阶专栏目录 前言 本章用于解决OpenLayers使用Cluster点聚合情况下,要素(Feature)出现有相同经纬度坐标时无法展开成单独图标的问题解决办法以及当缩放级别达到一定等级后强行展开聚合为单个点的功能。 本章展开后由于经纬度坐标还是同一个点,…

SAP 销售订单审批状态(查询/修改)

销售订单审批状态启用后&#xff0c;前端显示界面如下图 销售订单审批状态读取&#xff1a;STATUS_READ 销售订单审批状态修改&#xff1a;I_CHANGE_STATUS 销售订单审批状态读取 代码样例如下&#xff1a; DATA: lv_objnr TYPE vbak-objnr,lv_objnr_t TYPE jsto-objnr,l…

难道说 IT行业的下一个风口是鸿蒙开发吗?

按往年的习俗&#xff0c;在年底之季有很多HC都会缩减&#xff0c;尤其当下各种裁员的情况下&#xff0c;不管你是在哪个传统开发行业&#xff0c; 如&#xff1a;C/C、Java、前端、后端……等多少都会一股互联网寒流的影响。而今年却出现了一个怪现象&#xff0c;有个岗位在这…

【欢迎您的到来】这里是开源库get_local_info作者的付费专栏

您好&#xff0c; 我是带剑书生&#xff0c;开源库get_local_info的作者&#xff0c;欢迎您的到来&#xff0c;这里是我的付费专栏&#xff0c;会用更简洁的语言&#xff0c;更通俗的话语&#xff0c;来帮助您更好的学习rust&#xff0c;这里不仅仅讲解Rust在某些应用功能实现上…

Java可视化物联网智慧工地综合云平台源码 私有化部署

智慧工地平台围绕建筑施工人、物、事的安全管理为核心&#xff0c;对应研发了劳务实名制、视频监控、扬尘监测、起重机械安全监测、安全帽监测等功能一体化管理的解决方案。 智慧工地是聚焦工程施工现场&#xff0c;紧紧围绕人、机、料、法、环等关键要素&#xff0c;综合运用…

智慧矿山知识点总结

目录 1.第一章数字矿山的定义、基本特征和功能数字矿山的框架结合专业&#xff0c;如何发挥专业优势参与数字矿山建设&#xff08;GPT&#xff09; 2.第二章矿区地质构造和生态环境信息都包括哪些内容地球探测信息技术分类矿山品味与储量矿量估算 3.第三章矿山空间信息获取的仪…

RT-Thread Studio学习(十四)ADC

RT-Thread Studio学习&#xff08;十四&#xff09;ADC 一、简介二、新建RT-Thread项目并使用外部时钟三、启用ADC四、测试 一、简介 本文将基于STM32F407VET芯片介绍如何在RT-Thread Studio开发环境下使用ADC设备。硬件及开发环境如下&#xff1a; OS WIN10STM32F407VET6STM…