在笔者看过的众多编程书籍里面,《PHP&MySQL 范例精解——创建/修改/复用》这本书明确提出了一个非常有效的方法:找到工业级代码范例,然后“Create-Modify-Reuse”,这是笔者认为最好的学习方法.../p/137884434 1.4. smart pointer C++11标准在充分借鉴和吸收了boost库中智能指针的设计思想,引入了三种类型的智能指针,即 std::unique_ptr、std::...shared_ptr和 std::weak_ptr1)std::unique_ptr std::unique_ptr sp = std::make_unique(123); std::unique_ptr...右值引用与移动构造函数 本节参考: 程序喵大人:左值引用、右值引用、移动语义、完美转发,你知道的不知道的都在这里 作用:右值引用与std::move结合,减少对象拷贝 附:move函数实现 1.7...://github.com/google/googletest/blob/master/googletest/docs/advanced.md Google Mock官方文档: 入门: https:/
1.引入 C++17之后,C++标准库提供了std::optional,它是一个管理可选包含值的类模板。可选类型或有时也称为Maybe类型表示可选值的封装。...这意味着每个可选类型对象都需要额外的堆内存分配,这可能会导致内存开销增加。 不能存储空值:std::unique_ptr要求始终持有一个有效的指针,因此无法表示空值。...如果你需要表示一个可选类型的空值状态,你可能需要引入其他的标志来表示空值状态。 对于第二点,给个示例,当直接获取数据是,此时应该预期返回空值,而不是nullptr。...,继续优化,我们不用unique_ptr,回到第一个版本,干掉bool变量不就解决了一开始的内存对齐问题吗。...实现它的一种方法是使用std::aligned_storage为所包含的对象保留空间,随后用placement new,即使用new运算符在现有位置构造一个对象。
但像java等其他一些语言则不会有这样的问题,为什么呢,因为它们有很好的处理内存的方法,比如java的垃圾回收机制,现在,我们c++终于也有了智能指针。 1....但weak_ptr没有共享资源,它的构造不会引起指针引用计数的增加。同样,在weak_ptr析构时也不会导致引用计数的减少,它只是一个静静地观察者。...(); //w.expired()为true,返回空的shared_ptr;否则返回指向w的shared_ptr 1.3 std::unique_ptr uniqut_ptr是一种对资源具有排他性拥有权的智能指针...,即一个对象资源只能同时被一个unique_ptr指向。...unique_ptr可以作为函数的返回值 unique_ptr GetPtr(); //function getthe unique pointer unique_ptr pT = GetPtr
,两个指针将同时指向同一个string对象,这显然是不能被接受的,因为程序试图删除同一个对象两次,分别发生在ps和vication过期时,要解决这个问题,可以考虑下面几种方案: 定义赋值运算符,使之指向深复制...其中,auto_ptr和unique_ptr采用的就是这种策略,但unique_ptr的策略会更加的严格。 创建更加智能的智能指针,跟踪引用特定对象的智能指针数。这称为引用计数。...; ... } 上面的程序中,方法demo()返回一个临时变量temp,然后ps接管了原本归还的unique_ptr所有的对象,而后返回的unique_ptr被销毁,这是正确的,没什么问题。...总结一下就是: 如果程序试图将一个unique_ptr赋给另外一个时,如果源unique_ptr是一个临时右值,编译器允许这样的操作,相反,如果这个unique_ptr会存在一定的时间,那么这将会被编译器禁止...如果实在需要这种赋值操作,安全的重用这种指针,可以给他赋新值,这就引出了另外一个标准函数库中的函数:std::move()通过它,你可以实现将unique_ptr赋值给另外一个。
要避免这种问题,方法有多种: (1)定义陚值运算符,使之执行深复制。这样两个指针将指向不同的对象,其中的一个对象是另一个对象的副本,缺点是浪费空间,所以智能指针都未采用此方案。...每种方法都有其用途,但为何要摒弃auto_ptr呢? 下面举个例子来说明。...虽然这三种方法都可行,但方法1和方法2都需要程序员手动控制,麻烦且容易出错。这里主要介绍一下第三种方法,使用弱引用的智能指针std:weak_ptr来打破循环引用。...如果函数使用new分配内存,并返还指向该内存的指针,将其返回类型声明为unique_ptr是不错的选择。这样,所有权转让给接受返回值的unique_ptr,而该智能指针将负责调用delete。...在unique_ptr为右值时,可将其赋给shared_ptr,这与将一个unique_ptr赋给另一个unique_ptr需要满足的条件相同,即unique_ptr必须是一个临时的对象。
> p400 虽然使用动态内存有时是必要的,但众所周知,正确地管理动态内存是非常棘手的。...无法进行左值unique_ptr复制构造,也无法进行左值复制赋值操作,但允许临时右值赋值构造和赋值。std::move。把右值转换为左值。...T的数组对象 unique_ptr up(); //空的unique_ptr,接受一个D类型的删除器D,使用D释放内存 unique_ptr up(new T()); //定义unique_ptr...,同时指向类型为T的对象,接受一个D类型的删除器d,使用删除器d来释放内存 删除器 利用一个仿函数实现一个删除器 class DestructTest { public: void operator...1,p接管对p1指针的管控 up.reset(p1,d); //将up重置为p1(的值),up管控的对象计数减1并使用d作为删除器 交换 std::swap(p1,p2); //交换p1 和p2 管理的对象
将大象(资源)从一台冰箱(对象)移动到另一台冰箱,这个行为是如此自然,没有任何人会采用先复制大象,再销毁大象这样匪夷所思的方法。...右值引用至少可以解决以下场景中的移动语义缺失问题: 1.按值传入参数 按值传参是最符合人类思维的方式。基本的思路是,如果传入参数是为了将资源交给函数接受者,就应该按值传参。...上面两种形式分别返回栈上的左值和右值,但都适用移动语义(unique_ptr 不支持拷贝)。...但实际上 vector 并不复制对象,而只是“移动”对象。所以随着移动语义的引入,std::unique_ptr 放入 std::vector 成为理所当然的事情。...unique_ptr 是非常轻量的封装,存储空间等价于裸指针,但安全性强了一个世纪。实际中需要共享所有权的对象(指针)是比较少的,但需要转移所有权是非常常见的情况。
,源指针被置为空 //如果复制了一个 std::unique_ptr,会得到两个指向同一个资源的 std::unique_ptr,这两者都认为自己拥有该资源,需要析构两次 std::unique_ptr...,基类中必须具备一个虚析构函数 }; //改进的返回值型别 template<typename......operator =() 重载了 = 赋值号,从而可以将 nullptr 或者一个右值 unique_ptr 指针直接赋值给当前同类型的 unique_ptr 指针。...release() 释放当前 unique_ptr 指针对所指堆内存的所有权,但该存储空间并不会被销毁。...*/ /** 移动构造函数 与 复制构造函数的区别: 从一个 已有 std::shsred_ptr移动构造一个新的 std::shared_ptr会将 源 std::shared_ptr置空,这意味着一但新的
(43 == mock_api.call()); } } How C++ Resolves a Function Call 讲的非常细节,把编译器处理的整个流程顺了一遍 Does throw x implicit-move...Let’s ask SFINAE 简单说就是这么一段代码,throw v v本身是不是move的 std::unique_ptr a(std::unique_ptr p) {...// OK: implicit move (since C++11ish) } void b(std::unique_ptr p) { auto v = std::make_unique...可以Godbolt自己调一下看看 Counting the number of fields in an aggregate in C++20 读着读着发现就是magic_get/boost.pfr的方法...一个actor框架。
例如写一个内存区域时没控制好长度,越界了,把其他字段的值破坏了,这个时候再使用这个被破坏的字段就会出现崩溃; 内存被重复释放。...加了日志后,我们发现当接受一个新连接时: HttpSession 类构造了一次,无析构; HttpConnection 类构造一次,析构一次 断开连接时: HttpSession 类析构一次,然后崩溃。...但是,接下来的一行,却将该 HttpConnection 对象的原始指针传给了 HttpSession 对象, HttpSession 对象内部用另外一个 std::unique_ptr 对象 m_spConnection...是可以正常使用的,所以,我们将 HttpSession 的第一个参数修改成右值引用: class HttpSession { public: HttpSession(std::unique_ptr...,尤其是在和左值、右值、移动构造、std::move 、std::forward 等特性结合使用时,需要多加小心。
构造函数 其构造函数接受一个 T* ptr 参数,表示接管其生命周期,同时 new 一个 bookkeeping area (alloc 是有可能导致异常的,因此该 ctor 并不保证 noexcept...sp2 unique_ptr up(...); up = up2; 编译违法,unique_ptr 只接受 move ctor (即 move constructor) 和 move = (即 move...assignment operator) shared_ptr 的 ctor 接受 右值 unique_ptr,即 shared_ptr ps(move(up)); 然后 up 失去对 ptr 的 ownership...从 C++11 开始一直都可以正确处理 new[] std::enable_shared_from_this 如果类的方法想返回指向 this 的 shared_ptr,使用return std::shared_ptr...解决方法: 应当至少使用一个 weak_ptr,具体情况具体分析。
,或者指涉到 定义 lambda的作用域内的形参的引用,一旦由 lambda 所创建的闭包越过了该局部变量或形参的生命周期,那么闭包内的引用就会空悬 //情况1: //定义一个元素为筛选函数的容量,其中每个筛选函数都接受一个...int,并返回一个 bool 以表示传入的值是否满足筛选条件 //情况1: //定义一个元素为筛选函数的容量,其中每个筛选函数都接受一个 int,并返回一个 bool 以表示传入的值是否满足筛选条件...* lambda是值涉到局部变量divisor的引用,但该变量在addDivisorFilter返回时就不存在了。...,对divisor的指涉可能空悬 }); //按值捕获:按值捕获一个指针以后,在 lambda创建的闭包中持有的是这个指针的副本,但你并没有办法 //阻止 lambda之外的代码去针对该指针实施...* 如果发现该 lambda在其他语境中有用,例如,加入到filters容器中成为一个函数元素,然后被复制并粘贴 * 到其他闭包 比 divisor生命周期更长的语境中的话,你就又被拖回空悬的困境了
例如 TCP 连接中我封装一个 accept 函数接收请求,那么应该是这样的: Socket accept(); 这就带来一个问题,采用对象作返回值,这里面有一个对象复制的过程。...这就是用于 auto_ptr 和 unique_ptr 的策略,但 unique_ptr 的策略更严格。 创建智能更高的指针,跟踪引用特定对象的智能指针数,这称为引用计数。...,也就是不能放在等号的左边(函数的参数和返回值例外),这一定程度上避免了一些误操作导致指针所有权转移,然而 unique_str 依然有提供所有权转移的方法: std::move。...这样,所有权转让给接受返回值的 unique_ptr,而该智能指针将负责调用 delete。...另外,如果按值而不是按引用给 show() 传递对象,for_each() 将非法,因为这将导致使用一个来自 vp 的非临时 unique_ptr 初始化 pi,而这是不允许的,编译器将发现错误使用 unique_ptr
> p1(new int); unique_ptr p2(std::move(p1)); unique_ptr(unique_ptr &&src) 是unique的移动构造函数,它接收一个右值引用作为参数...当你使用std::move函数将一个unique_ptr对象转化为右值引用并将其传递给另一个unique_ptr对象来初始化时,就会调用这个构造函数 unique_ptr& operator=(unique_ptr...当你使用std::move函数将一个unique_ptr对象转化为右值引用并将其赋值给另一个unique_ptr对象来初始化时,就会调用这个运算符 第三行代码创建一个unique_ptr对象p1...,并且使用new int动态分配内存来存储一个int类型的对象 第四行代码创建另一个unique_ptr对象p2,并且使用std::move()将p1转化为右值引用并传递给p2的移动构造函数,...这样p1的所有权转移给p2,p1变为空指针 三四行代码,不涉及构造赋值运算符,只涉及到移动构造函数 这时候肯定会说,那和auto_ptr也一样啊,但unique_ptr p2(std::move
include-what-you-use[6]是一个可以帮我们确定需要哪些头文件的工具。 减少预处理器的工作 这是“隔离频繁更改的头文件”和“不要包含不需要的头文件”的一般形式。...建议只将经常使用但很少更改的头文件定义为预编译头文件(例如系统头文件和库头文件),以减少编译时间。但必须记住,使用预编译头文件有几个缺点: 预编译头文件不可移植。 生成的PCH文件依赖于机器。...对于大多数代码,下面这么一个简单的定义: ModelObject(ModelObject &&) = default; ...就足够了,不过MSVC2013似乎不支持这段代码。...>(); 目前的最佳实践也建议从工厂函数返回unique_ptr,然后在必要时将unique_ptr转换为shared_ptr。...double是C++中浮点值的默认类型,因此推荐作为默认选项。 参考下面的文章获取更多信息: double or float, which is faster?
如果一元函数返回一个布尔值,则该函数称为谓词。 二元函数:接受两个参数的函数,如 f(x, y)。如果二元函数返回一个布尔值,则该函数称为二元谓词。...表达式 二元函数接受两个参数,还可返回一个值。...这种内部使用一种容器但呈现另一种容器的行为特征的容器称为自适应容器。主要有三种类型:stack,queue,priority_queue。STL stack是一个模板类,要使用它,必须包含头文件。..."); bitset的成员方法 STL bitset的缺点之一是不能动态地调整长度。...要使用std:unique_ptr,必须包含头文件。
unique_ptr 一个unique_ptr独享它指向的对象。也就是说,同时只有一个unique_ptr指向同一个对象,当这个unique_ptr被销毁时,指向的对象也随即被销毁。...举个简单的例子,假如你打开了一个连接,获取到了一个文件描述符,现在你想通过unique_ptr来管理,希望在不需要的时候,能够借助unique_ptr帮忙关闭它。...如: std::unique_ptr up1(new int(42)); std::unique_ptr up2(up1.release()); up2接受up1 release之后的指针...: std::unique_ptr up1(new int(42)); std::unique_ptr up2(std::move(up1)); 在函数中的使用 还记得在《传值和传指针有什么区别...//test(std::move(up));//这种方式也可以 return 0; } 作为返回值 unique_ptr可以作为参数返回: //来源:公众号【编程珠玑】 #include<iostream
一、基础概念 谈到C++,绕不开的一个特性是智能指针,智能指针见字如面:有两个概念:一个是指针,一个是“智能”。 和类似指针的相同使用方式使用他,它可以托管任何使用“new”创建的对象。...2.2.1 weak_ptr的初始化和赋值 weak_ptr默认是空的,不指到任何对象。它可以接受shared_ptr或者另一个weak_ptr的赋值。...如果不存在,会得到空的shared_ptr。 weak_ptr默认是空的,不指像任何对象。它可以接受shared_ptr或者另一个weak_ptr的赋值。... p1(createTest()); // 调用了移动构造函数,并读取了createTest的返回rvalue值 std::unique_ptr p2; p2...= createTest(); // 调用了移动赋值函数,并读取了createTest的返回rvalue值 std::unique_ptr p3; p3 = std
智能指针是行为类似于指针的类对象,但这种对象还有其他功能。使用指针指向一块新申请的内存的过程中,有时忘记释放新申请的内存,导致内存泄漏。为了防止该问题的发生,C++提供了智能指针模板类。...有关智能指针的注意事项 常规的指针在使用的过程中两个指针可能会指向同一个对象,这是不能接受的,因为程序在结束的时候会存在删除同一对象两次的问题,如下例: std::string* ps (new...相比auto_ptr,unique_ptr另外一个优点就是它有一个可以用于数组的变体。...但unique_ptr有delete和delete[]两个版本,它可以与new一起使用,也可以与new[]一起使用。同样的,shared_ptr也支持与new一起使用,不支持new[]的使用。...如何选择合适的指针 程序要使用多个指向同一个对象的指针 使用shared_ptr。 程序不需要多个指向同一个对象的指针 使用unique_ptr。
领取专属 10元无门槛券
手把手带您无忧上云