C++的对象优化经验

这篇具有很好参考价值的文章主要介绍了C++的对象优化经验。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

先看一个例子:

class Test{
private:
    int ma;

public:
    Test(int a = 0) : ma(a) { cout << "Test(int a)" << endl; }
    ~Test() { cout << "~Test" << endl; }
    Test(const Test &t)
    {
        ma = t.ma;
        cout << "Test(const Test&t)" << endl;
    }
    Test &operator=(const Test &t)
    {
        ma = t.ma;
        cout << "Test& operator=(const Test&t)" << endl;
    }
};

C++编译器对于对象的构造优化:用临时对象生成新对象的时候,临时对象就不产生了,直接构造新对象就可以了,而不是先构造临时对象,然后拷贝构造给新定义的对象

eg:

    Test t2(t1);//拷贝构造
    Test t3=t1; //拷贝构造  因为t2 ,t3都是未定义的
    Test t4=Test();//和Test t4()是没有区别的,并不是先构造一个
                    //临时对象然后拷贝构造给t4

C++的对象优化经验,现代C++,前端,服务器,c++

而对于已有对象进行构造赋值的时候,就是构造临时对象,然后调用赋值语句

eg:

    Test t3=t1; //拷贝构造  因为t2 ,t3都是未定义的

    t3=Test(20);   //构造临时,赋值

这个~Test就是产生的临时对象Test(20)的析构

eg:

显示生产临时对象,隐式生成临时对象

   Test t1;
    Test t2(t1);//拷贝构造
    Test t3=t1; //拷贝构造  因为t2 ,t3都是未定义的
    Test t4=Test();//和Test t4()是没有区别的,并不是先构造一个
                    //临时对象然后拷贝构造给t4

    t3=(Test)30;  //int ->Test(int) 显示
    t3=50;  //  int ->Test(int)  隐式  ,编译器都要看有没有Test(int)的构造函数

C++的对象优化经验,现代C++,前端,服务器,c++

eg:

指针不要指向临时对象,因为临时对象会析构,指针指向一个已经析构的对象,这样不安全

引用可以指向临时对象,因为是别名

 Test *p=&Test(55);  //高版本编译器已经报错

    const Test &ps=Test(60);

所以指针这种都是要new一个出来,最后delete

    Test* p = new Test(55);
    delete p;

C++的对象优化经验,现代C++,前端,服务器,c++

堆上分配的内存,不delete,是不会自动析构的,会泄漏内存

在实现string的时候对于拷贝构造和赋值,指针都需要都产生临时对象,不断的new delete效率很低,所以优化的时候引用右值拷贝,赋值

对于vector的push_back,你给他传左值,他就调左值的拷贝构造,你给他传右值,就会调右值的拷贝构造.vector怎么实现的呢?

ans:  在外面传的是用过模板类型推导和引用折叠+完美转发实现

注意右值引用变量其实是一个左值

int &&b=20;
int &c=b;

拷贝构造其实就是初始化的方式

什么是初始化的方式? 就是式子左边的还没有定义出来

xxx t1=已定义的或者匿名临时对象
xxx t1(已定义的或者匿名临时对象)

赋值方式就是,左边,右边都已经定义存在了

xxx t1
xxx  t2
t1=t2; 赋值

 emplace

像STL里面emplace系列的api都是通过可变参模板和引用折叠,forward实现的

 // emplace_back方法    
template <typename... Args>
    void emplace_back(Args&&... args) {
        if (size_ >= capacity_) {
            // 扩容
            reserve(capacity_ * 2);
        }
        // 在尾部直接构造对象
        new (data_ + size_) T(std::forward<Args>(args)...);
        ++size_;
    }

    // emplace方法
    template <typename... Args>
    void emplace(size_t pos, Args&&... args) {
        if (pos > size_) {
            throw std::out_of_range("Invalid position");
        }
        if (size_ >= capacity_) {
            // 扩容
            reserve(capacity_ * 2);
        }
        // 后移元素
        for (size_t i = size_; i > pos; --i) {
            data_[i] = std::move(data_[i-1]);
        }
        // 在指定位置直接构造对象
        new (data_ + pos) T(std::forward<Args>(args)...);
        ++size_;
    }

可变参模板部分补充

类模板的友元_模板友元

可变参数模板_c++可变参数模板类_右大臣的博客-CSDN博客

下面是对我这两个文章的一点补充

template<typename ...Args>
void add(Args&&... args)
{
    ((cout<<"args:"<<forward<Args>(args)<<endl),...);
}
int main()
{
    add(12,3,54,5);
    getchar();
    return 0;
}

C++的对象优化经验,现代C++,前端,服务器,c++

 这里使用了折叠表达式 `(expression, ...)` 来展开参数包,并在每次展开时输出参数的值。这样,我们可以处理任意数量的参数,而不仅仅限于一个参数。

请注意,折叠表达式 `(expression, ...)` 是C++17引入的语法,它允许将一系列表达式以逗号分隔的形式展开。

平常我们自己写可能最多的是这么写的

template<typename T>
void add(T&& arg)
{
    std::cout<<"accept last args"<<endl;
    std::cout << arg << " ";
}

template<typename T, typename... Args> // 
void add(T&& arg, Args&&... args)
{
    std::cout << arg << " ";
    add(std::forward<Args>(args)...);  //forward不是必须的,这里只是做个完美转发
}
int main()
{
    add(12,3,54,5);
    getchar();
    return 0;
}

C++的对象优化经验,现代C++,前端,服务器,c++

 第一个add函数是一个递归的终止条件,它用于处理参数包中只有一个参数的情况。当参数包中只剩下一个参数时,递归调用将停止,这时只剩下最后一个参数需要处理。

在这个例子中,第一个add函数接收一个右值引用参数T&& arg,并输出该参数的值。这个函数作为递归的终止条件,用于处理参数包中只有一个参数的情况。

然后,第二个add函数是一个递归函数模板,它接收一个右值引用参数T&& arg和一个参数包Args&&... args。它首先输出当前参数的值,然后使用递归调用add(std::forward<Args>(args)...),将剩余的参数包传递给下一次递归调用。

通过递归调用,这个函数模板可以依次处理参数包中的每个参数,直到参数包为空。这样可以实现对参数包中所有参数的输出。

因此,第一个add函数是为了处理参数包中只有一个参数的情况,而第二个add函数则用于递归地处理参数包中的多个参数。

当你add只给一个参数的时候就会调最上面那个add

    add(12);

C++的对象优化经验,现代C++,前端,服务器,c++

模板元博大精深,后面这块只是对我之前写的一些博客的补充 文章来源地址https://www.toymoban.com/news/detail-602331.html

到了这里,关于C++的对象优化经验的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • [1Panel]开源,现代化,新一代的 Linux 服务器运维管理面板

    本期测评试用一下1Panel这款面板。1Panel是国内飞致云旗下开源产品。整个界面简洁清爽,后端使用GO开发,前端使用VUE的Element-Plus作为UI框架,整个面板的管理都是基于docker的,想法很先进。官方还提供了视频的使用教程,本期为大家按照本专栏的基本内容进行多方面的测评。

    2024年02月07日
    浏览(95)
  • 解决Nacos服务器连接问题:一次完整的排查经验分享

    🌷🍁 博主猫头虎(🐅🐾)带您 Go to New World✨🍁 🦄 博客首页 ——🐅🐾猫头虎的博客🎐 🐳 《面试题大全专栏》 🦕 文章图文并茂🦖生动形象🐅简单易学!欢迎大家来踩踩~🌺 🌊 《IDEA开发秘籍专栏》 🐾 学会IDEA常用操作,工作效率翻倍~💐 🌊 《100天精通Golang(基础

    2024年02月10日
    浏览(54)
  • 学习Linux的注意事项(使用经验;目录作用;服务器注意事项)

    本篇分享学习Linux过程中的一些经验 Linux严格区分大小写 Linux中所有内容以文件形式保存 ,包括硬件,Linux是以管理文件的方式操作硬件 硬盘文件是 /dev/sd[a-p] 光盘文件是 /dev/sr0 等 对于设置需要写入文件,命令行的设置在重启之后就会失效,只有下入文件才可以保存下来 文

    2024年02月11日
    浏览(74)
  • 为什么说 QUIC 协议是现代化网络通信的未来之路及如何实现QUIC服务器

    😄作者简介: 小曾同学.com,一个致力于测试开发的博主⛽️,主要职责:测试开发、CI/CD 如果文章知识点有错误的地方,还请大家指正,让我们一起学习,一起进步。😊 座右铭:不想当开发的测试,不是一个好测试✌️。 如果感觉博主的文章还不错的话,还请点赞、收藏哦

    2024年04月23日
    浏览(49)
  • Ubuntu是一种现代化的开源Linux操作系统,适用于企业服务器、桌面电脑、云和IoT物联网设备

    Ubuntu是一种现代化的开源Linux操作系统,适用于企业服务器、桌面电脑、云和IoT物联网设备。您可以从Ubuntu官网下载Ubuntu桌面版、Ubuntu服务器版、Ubuntu for Raspberry Pi和IoT设备版、Ubuntu Core以及所有Ubuntu版本。 Ubuntu是一种现代化的开源Linux操作系统,它适用于广泛的设备和应用场

    2024年01月16日
    浏览(72)
  • 前后端服务器分离时,前端如何上传图片到前端服务器?

    当前后端服务器分离时,前端上传图片到前端服务器可以采用以下几种方式: 1. 直接上传到前端服务器:可以通过使用HTML的`input type=\\\"file\\\"`元素,让用户选择图片文件并直接上传到前端服务器。前端服务器可以使用后端提供的API接口处理上传请求,然后将图片保存到前端服务

    2024年04月27日
    浏览(54)
  • 服务器性能优化方法

    一台服务器在单位时间里能处理的请求越多,服务器的能力越高,也就是服务器并发处理能力越强。 服务器的本质工作就是,争取以最快的速度将内核缓冲区中的用户请求数据一个不剩地都拿出来,然后尽快处理,再将响应数据放到一块又能够与发送数据的缓冲区中,接着处

    2024年02月07日
    浏览(43)
  • 服务器发版(前端如何自己连接服务器发版)

    1.下载FinalShell远程连接工具 http://www.hostbuf.com/downloads/finalshell_windows_x64.exe 2.打开exe 3.创建连接,SSH连接 4.新建完连接后,快速连接后列表中多了一条数据 5. 6.指令 which nginx 查找nginx文件夹所在位置 找到后cd到nginx 位置 进入nginx下的conf文件夹,找到nginx.conf配置转发 7.cd 到sbin文

    2024年01月17日
    浏览(51)
  • 最全对象存储(云盘)挂载本地主机或服务器

    分布式存储的应用场景相对于其存储接口,现在流行分为三种: 块存储 : 这种接口通常以QEMU Driver或者Kernel Module的方式存在,这种接口需要实现Linux的Block Device的接口或者QEMU提供的Block Driver接口,块存储一般体现形式是卷或者硬盘(比如windows里面看到的c盘),数据是按字节来

    2024年01月21日
    浏览(60)
  • 【迅搜07】基础对象概览(二)服务器与命令对象及数据传输原理

    在学习完最基础的 XS 对象和一些字段对象之后,我们今天将学习到的是 XS 的 PHP SDK 中非常核心的一个对象,那就是 XSServer 对象。从名字就可以看出,它是负责和服务端交互的,也就是 PHP 与 Xapian 的交互部分。要说搜索索引,最核心的应该是在索引和搜索的操作上,这两部分

    2024年02月20日
    浏览(41)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包