C++11中unique_ptr的使用
在C++中,动态内存的管理是通过一对运算符来完成的:new,在动态内存中为对象分配空间并返回一个指向该对象的指针,可以选择对对象进行初始化;delete,接受一个动态对象的指针,销毁该对象,并释放与之关联的内存。
动态内存的使用很容易出问题,因为确保在正确的时间释放内存是极其困难的。有时会忘记释放内存,在这种情况下会产生内存泄露;有时在尚有指针引用内存的情况下就释放了它,在这种情况下就会产生引用非法内存的指针。
为了更容易(同时也更安全)地使用动态内存,C++11标准库提供了两种智能指针(smart pointer)类型来管理动态对象。智能指针的行为类似常规指针,重要的区别是它负责自动释放所指的对象。C++11标准库提供的这两种智能指针的区别在于管理底层指针的方式:shared_ptr允许多个指针指向同一个对象;unique_ptr则"独占"所指向的对象。C++11标准库还定义了一个名为weak_ptr的辅助类,它是一种弱引用,指向shared_ptr所管理的对象。这三种类型都定义在memory头文件中。智能指针是模板类而不是指针。类似vector,智能指针也是模板,当创建一个智能指针时,必须提供额外的信息即指针可以指向的类型。默认初始化的智能指针中保存着一个空指针。智能指针的使用方式与普通指针类似。解引用一个智能指针返回它指向的对象。如果在一个条件判断中使用智能指针,效果就是检测它是否为空。
In C++, a smart pointer is implemented as a template class that mimics, by means of operator overloading, the behaviors of a traditional (raw) pointer, (e.g. dereferencing, assignment) while providing additional memory management features.
std::unique_ptr is a smart pointer that retains sole ownership of an object through a pointer and destroys that object when the unique_ptr goes out of scope. No two unique_ptr instances can manage the same object.
The object is destroyed and its memory deallocated when either of the following happens: (1)、the managing unique_ptr object is destroyed; (2)、the managing unique_ptr object is assigned another pointer via operator= or reset().
A unique_ptr may alternatively own no object, in which case it is called empty.
Only non-const unique_ptr can transfer the ownership of the managed object to another unique_ptr. The lifetime of an object managed by const std::unique_ptr is limited to the scope in which the pointer was created.
std::unique_ptr may be constructed for an incomplete type T. Conversely, std::shared_ptr can't be constructed from a raw pointer to incomplete type, but can be destroyed where T is incomplete.
A unique_ptr does not share its pointer. It cannot be copied to another unique_ptr, passed by value to a function, or used in any Standard Template Library (STL) algorithm that requires copies to be made. A unique_ptr can only be moved. This means that the ownership of the memory resource is transferred to another unique_ptr and the original unique_ptr no longer owns it.
When using unique_ptr, there can be at most one unique_ptr pointing at any one resource.When that unique_ptr is destroyed, the resource is automatically reclaimed.Because there can only be one unique_ptr to any resource, any attempt to make a copy of a unique_ptr will cause a compile-time error. However, unique_ptr can be moved using the new move semantics.
shared_ptr, allows for multiple pointers to point at a given resource. When the very last shared_ptr to a resource is destroyed, the resource will be deallocated. shared_ptr uses reference counting to track how many pointers refer to a resource, so you need to be careful not to introduce any reference cycles.
A unique_ptr is a container for a raw pointer, which the unique_ptr is said to own. A unique_ptr explicitly prevents copying of its contained pointer (as would happen with normal assignment), but the std::move function can be used to transfer ownership of the contained pointer to another unique_ptr. A unique_ptr cannot be copied because its copy constructor and assignment operators are explicitly deleted.
everything you can do with auto_ptr, unique_ptr will do as well.
There are two kinds of unique_ptr, one for scalars (i.e. non-arrays) and one for arrays:
(1)、unique_ptr<double> can hold a scalar of type double;
(2)、unique_ptr<double[]> can hold an array of double values with an unknown number of elements.
std::unique_ptr是C++11标准中用来取代std::auto_ptr的指针容器(在C++11中,auto_ptr被废弃)。它不能与其它unique_ptr类型的指针对象共享所指对象的内存。这种”所有权”仅能够通过标准库的move函数来转移。unique_ptr是一个删除了拷贝构造函数、保留了移动构造函数的指针封装类型。
一个unique_ptr"拥有"它所指向的对象。与shared_ptr不同,某个时刻只能有一个unique_ptr指向一个给定对象。当unique_ptr被销毁时,它所指向的对象也被销毁。与shared_ptr不同,在C++11中,没有类似make_shared的标准库函数返回一个unique_ptr。当定义一个unique_ptr时,需要将其绑定到一个new返回的指针上。类似shared_ptr,初始化unique_ptr必须采用直接初始化形式。由于一个unique_ptr拥有它指向的对象,因此unique_ptr不支持普通的拷贝或赋值操作。虽然不能拷贝或赋值unique_ptr,但可以通过调用release或reset将指针的所有权从一个(非const)unique_ptr转移给另一个unique。
调用release会切断unique_ptr和它原来管理的对象间的联系。release返回的指针通过被用来初始化另一个智能指针或给另一个智能指针赋值。如果不用另一个智能指针来保存release返回的指针,程序就要负责资源的释放。
不能拷贝unique_ptr的规则有一个例外:我们可以拷贝或赋值一个将要被销毁的unique_ptr,最常见的例子是从函数返回一个unique_ptr。
类似shared_ptr,unique_ptr默认情况下用delete释放它指向的对象。与shared_ptr一样,可以重载一个unique_ptr中默认的删除器。但是,unique_ptr管理删除器的方式与shared_ptr不同。
下图列出了unique_ptr支持的操作(来源于C++ Primer Fifth Edition 中文版):
下面是从其他文章中copy的测试代码,详细内容介绍可以参考对应的reference:
#include "unique_ptr.hpp"
#include <iostream>
#include <memory>
#include <string>
#include <cstdlib>
#include <utility>
#include <vector>
#include <algorithm>
#include <cassert>
#include <fstream>
#include <functional>namespace unique_ptr_ {///
// reference: http://en.cppreference.com/w/cpp/memory/unique_ptr
struct Foo
{Foo() { std::cout << "Foo::Foo\n"; }~Foo() { std::cout << "Foo::~Foo\n"; }void bar() { std::cout << "Foo::bar\n"; }
};void f(const Foo &)
{std::cout << "f(const Foo&)\n";
}int test_unique_ptr1()
{std::unique_ptr<Foo> p1(new Foo); // p1 owns Fooif (p1) p1->bar();{std::unique_ptr<Foo> p2(std::move(p1)); // now p2 owns Foof(*p2);p1 = std::move(p2); // ownership returns to p1std::cout << "destroying p2...\n";}if (p1) p1->bar();// Foo instance is destroyed when p1 goes out of scopereturn 0;
}//
// reference: http://www.cplusplus.com/reference/memory/unique_ptr/unique_ptr/
int test_unique_ptr2()
{std::default_delete<int> d;std::unique_ptr<int> u1;std::unique_ptr<int> u2(nullptr);std::unique_ptr<int> u3(new int);std::unique_ptr<int> u4(new int, d);std::unique_ptr<int> u5(new int, std::default_delete<int>());std::unique_ptr<int> u6(std::move(u5));std::unique_ptr<int> u7(std::move(u6));std::unique_ptr<int> u8(std::auto_ptr<int>(new int));std::cout << "u1: " << (u1 ? "not null" : "null") << '\n';std::cout << "u2: " << (u2 ? "not null" : "null") << '\n';std::cout << "u3: " << (u3 ? "not null" : "null") << '\n';std::cout << "u4: " << (u4 ? "not null" : "null") << '\n';std::cout << "u5: " << (u5 ? "not null" : "null") << '\n';std::cout << "u6: " << (u6 ? "not null" : "null") << '\n';std::cout << "u7: " << (u7 ? "not null" : "null") << '\n';std::cout << "u8: " << (u8 ? "not null" : "null") << '\n';return 0;
}//
// reference: http://eli.thegreenplace.net/2012/06/20/c11-using-unique_ptr-with-standard-library-containers
struct Foo_0 {Foo_0() { std::cerr << "Foo_0 [" << this << "] constructed\n"; }virtual ~Foo_0() { std::cerr << "Foo_0 [" << this << "] destructed\n"; }
};void sink(std::unique_ptr<Foo_0> p) {std::cerr << "Sink owns Foo_0 [" << p.get() << "]\n";
}std::unique_ptr<Foo_0> source() {std::cerr << "Creating Foo_0 in source\n";return std::unique_ptr<Foo_0>(new Foo_0);
}int test_unique_ptr3()
{std::cerr << "Calling source\n";std::unique_ptr<Foo_0> pmain = source(); // Can also be written as// auto pmain = source();std::cerr << "Now pmain owns Foo [" << pmain.get() << "]\n";std::cerr << "Passing it to sink\n";// sink(pmain); // ERROR! can't copy unique_ptrsink(move(pmain)); // OK: can move it!std::cerr << "Main done\n";return 0;
}// reference: http://www.codeguru.com/cpp/article.php/c17775/The-Smart-Pointer-That-Makes-Your-C-Applications-Safer--stduniqueptr.htm
void func(int*)
{}int test_unique_ptr4()
{// default constructionstd::unique_ptr<int> up; //creates an empty object// initialize with an argumentstd::unique_ptr<int> uptr(new int(3));double *pd = new double;std::unique_ptr<double> uptr2(pd);// overloaded * and ->*uptr2 = 23.5;std::unique_ptr<std::string> ups(new std::string("hello"));int len = ups->size();// Reset() releases the owned resource and optionally acquires a new resource:uptr2.reset(new double); //delete pd and acquire a new pointeruptr2.reset(); //delete the pointer acquired by the previous reset() call// If you need to access the owned pointer directly use get()func(uptr.get());// Unique_ptr has implicit conversion to bool.// This lets you use unique_ptr object in Boolean expressions such as this:if (ups) //implicit conversion to boolstd::cout << *ups << std::endl;elsestd::cout << "an empty smart pointer" << std::endl;// Array Support: Unique_ptr can store arrays as well.// A unique_ptr that owns an array defines an overloaded operator [].// Obviously, the * and -> operators are not available.// Additionally, the default deleter calls delete[] instead of delete:std::unique_ptr<int[]> arrup(new int[5]);arrup[0] = 5;// std::cout << *arrup << std::endl; //error, operator * not defined // Compatibility with Containers and Algorithms// You can safely store unique_ptr in Standard Library containers and let algorithms manipulate sequences of unique_ptr objects.std::vector<std::unique_ptr<int>> vi;vi.push_back(std::unique_ptr<int>(new int(0))); // populate vectorvi.push_back(std::unique_ptr<int>(new int(3)));vi.push_back(std::unique_ptr<int>(new int(2)));std::sort(vi.begin(), vi.end()); // result: {0, 2, 3}return 0;
}//
template <typename T>
class Add {
public:T add_sub(T a, T b){return (a + b) * (a - b);}
};int test_unique_ptr5()
{std::unique_ptr<Add<int>> tt(new Add<int>());int a{ 10 }, b{ 5 };std::cout << tt->add_sub(a, b) << std::endl;return 0;
}//
int test_unique_ptr6()
{std::unique_ptr<int[]> tmp(new int[100]);std::for_each(tmp.get(), tmp.get() + 100, [](int& n) {n = 66; });std::cout << tmp[99] << std::endl;return 0;
}///
// reference: https://en.cppreference.com/w/cpp/memory/unique_ptr
struct B {virtual void bar() { std::cout << "B::bar\n"; }virtual ~B() = default;
};
struct D : B
{D() { std::cout << "D::D\n"; }~D() { std::cout << "D::~D\n"; }void bar() override { std::cout << "D::bar\n"; }
};// a function consuming a unique_ptr can take it by value or by rvalue reference
std::unique_ptr<D> pass_through(std::unique_ptr<D> p)
{p->bar();return p;
}void close_file(std::FILE* fp) { std::fclose(fp); }int test_unique_ptr7()
{std::cout << "unique ownership semantics demo\n";{auto p = std::make_unique<D>(); // p is a unique_ptr that owns a Dauto q = pass_through(std::move(p));assert(!p); // now p owns nothing and holds a null pointerq->bar(); // and q owns the D object} // ~D called herestd::cout << "Runtime polymorphism demo\n";{std::unique_ptr<B> p = std::make_unique<D>(); // p is a unique_ptr that owns a D// as a pointer to basep->bar(); // virtual dispatchstd::vector<std::unique_ptr<B>> v; // unique_ptr can be stored in a containerv.push_back(std::make_unique<D>());v.push_back(std::move(p));v.emplace_back(new D);for (auto& p : v) p->bar(); // virtual dispatch} // ~D called 3 timesstd::cout << "Custom deleter demo\n";std::ofstream("demo.txt") << 'x'; // prepare the file to read{std::unique_ptr<std::FILE, decltype(&close_file)> fp(std::fopen("demo.txt", "r"), &close_file);if (fp) // fopen could have failed; in which case fp holds a null pointerstd::cout << (char)std::fgetc(fp.get()) << '\n';} // fclose() called here, but only if FILE* is not a null pointer// (that is, if fopen succeeded)std::cout << "Custom lambda-expression deleter demo\n";{std::unique_ptr<D, std::function<void(D*)>> p(new D, [](D* ptr){std::cout << "destroying from a custom deleter...\n";delete ptr;}); // p owns Dp->bar();} // the lambda above is called and D is destroyedstd::cout << "Array form of unique_ptr demo\n";{std::unique_ptr<D[]> p{ new D[3] };} // calls ~D 3 timesreturn 0;
}/
// reference: http://www.cplusplus.com/reference/memory/unique_ptr/~unique_ptr/
int test_unique_ptr8()
{auto deleter = [](int*p){delete p;std::cout << "[deleter called]\n";};std::unique_ptr<int, decltype(deleter)> foo(new int, deleter);std::cout << "foo " << (foo ? "is not" : "is") << " empty\n";return 0; // [deleter called]
}/
// reference: http://www.cplusplus.com/reference/memory/unique_ptr/get_deleter/
class state_deleter { // a deleter class with stateint count_;
public:state_deleter() : count_(0) {}template <class T>void operator()(T* p) {std::cout << "[deleted #" << ++count_ << "]\n";delete p;}
};int test_unique_ptr9()
{state_deleter del;std::unique_ptr<int> p; // uses default deleter// alpha and beta use independent copies of the deleter:std::unique_ptr<int, state_deleter> alpha(new int);std::unique_ptr<int, state_deleter> beta(new int, alpha.get_deleter());// gamma and delta share the deleter "del" (deleter type is a reference!):std::unique_ptr<int, state_deleter&> gamma(new int, del);std::unique_ptr<int, state_deleter&> delta(new int, gamma.get_deleter());std::cout << "resetting alpha..."; alpha.reset(new int);std::cout << "resetting beta..."; beta.reset(new int);std::cout << "resetting gamma..."; gamma.reset(new int);std::cout << "resetting delta..."; delta.reset(new int);std::cout << "calling gamma/delta deleter...";gamma.get_deleter()(new int);alpha.get_deleter() = state_deleter(); // a brand new deleter for alpha// additional deletions when unique_ptr objects reach out of scope// (in inverse order of declaration)return 0;
}//
// reference: http://www.cplusplus.com/reference/memory/unique_ptr/operator=/
int test_unique_ptr10()
{std::unique_ptr<int> foo;std::unique_ptr<int> bar;foo = std::unique_ptr<int>(new int(101)); // rvaluebar = std::move(foo); // using std::movestd::cout << "foo: ";if (foo) std::cout << *foo << '\n'; else std::cout << "empty\n";std::cout << "bar: ";if (bar) std::cout << *bar << '\n'; else std::cout << "empty\n";return 0;
}/
// reference: http://www.cplusplus.com/reference/memory/unique_ptr/release/
int test_unique_ptr11()
{std::unique_ptr<int> auto_pointer(new int);int * manual_pointer;*auto_pointer = 10;manual_pointer = auto_pointer.release();// (auto_pointer is now empty)std::cout << "manual_pointer points to " << *manual_pointer << '\n';delete manual_pointer;return 0;}///
// reference: http://www.cplusplus.com/reference/memory/unique_ptr/swap/
int test_unique_ptr12()
{std::unique_ptr<int> foo(new int(10)), foo2(new int(10));std::unique_ptr<int> bar(new int(20)), bar2(new int(20));foo.swap(bar);std::cout << "foo: " << *foo << '\n';std::cout << "bar: " << *bar << '\n';std::swap(foo2, bar2);std::cout << "foo2: " << *foo2 << '\n';std::cout << "bar2: " << *bar2 << '\n';return 0;
}void math_add(int* a)
{int b = ++(*a);delete a;fprintf(stdout, "add operation: %d\n", b);
}void math_subtract(int* a)
{int b = --(*a);delete a;fprintf(stdout, "subtraction operation: %d\n", b);
}int test_unique_ptr13()
{{std::unique_ptr<int, decltype(&math_add)> A(new int, &math_add);if (!A) {fprintf(stderr, "A is nullptr\n");return -1;}*A = 10;}{typedef std::unique_ptr<int, std::function<void(int*)>> Oper;Oper A(new int, math_add);*A = 10;Oper B(new int, math_subtract);*B = 10;}return 0;
}} // namespace unique_ptr_
GitHub:https://github.com/fengbingchun/Messy_Test
相关文章:

从这篇YouTube论文,剖析强化学习在工业级场景推荐系统中的应用
作者 | 吴海波转载自知乎用户吴海波【导读】本文作者根据两篇工业界背景的论文解答了 RL 在推荐场景需要解决的问题与困难,以及入门需要学习得相关知识点。2 个月前,业界开始流传 youtube 成功将 RL 应用在了推荐场景,并且演讲者在视频中说是…

java中两个Integer类型的值相比较的问题
转载自: https://www.cnblogs.com/xh0102/p/5280032.html 两个Integer类型整数进行比较时,一定要先用intValue()方法将其转换为int数之后再进行比较,因为直接使用比较两个Integer会出现问题。 总结: 当给Integer直接赋值时&#x…

C#共享内存实例 附源码
原文 C#共享内存实例 附源码 网上有C#共享内存类,不过功能太简单了,并且写内存每次都从开头写。故对此进行了改进,并做了个小例子,供需要的人参考。 主要改进点: 通过利用共享内存的一部分空间(以下称为“数据信息区”…
C++11中weak_ptr的使用
在C中,动态内存的管理是通过一对运算符来完成的:new,在动态内存中为对象分配空间并返回一个指向该对象的指针,可以选择对对象进行初始化;delete,接受一个动态对象的指针,销毁该对象,…

经典不过时,回顾DeepCompression神经网络压缩
作者 | 薰风初入弦转载自知乎导读:本文作者为我们详细讲述了 ICLR 2016 的最佳论文 Deep Compression 中介绍的神经网络压缩方法。神经网络压缩一直是一个重要的研究方向,而目前业界最认可的压缩方法莫过于 ICLR 2016 的最佳论文 Deep Compression&#…

区块链技术特点之去中心化特性
想知道更多关于区块链技术知识,请百度【链客区块链技术问答社区】 链客,有问必答!! 由于区块链技术去中心化的特性,其在我们生活中的很多重要领域(如金融、管理)等方面具有重要的意义。例如&…

Android APK反编译
转自:http://blog.csdn.net/ithomer/article/details/6727581 一、Apk反编译得到Java源代码 下载上述反编译工具包,打开apk2java目录下的dex2jar-0.0.9.9文件夹,内含apk反编译成java源码工具,以及源码查看工具。 apk反编译工具dex…
Java泛型进阶 - 如何取出泛型类型参数
在JDK5引入了泛型特性之后,她迅速地成为Java编程中不可或缺的元素。然而,就跟泛型乍一看似乎非常容易一样,许多开发者也非常容易就迷失在这项特性里。多数Java开发者都会注意到Java编译器的类型擦除实现方式,Type Erasure会导致关…

C++11中override的使用
override是C11中的一个继承控制关键字。override确保在派生类中声明的重载函数跟基类的虚函数有相同的声明。 override明确地表示一个函数是对基类中一个虚函数的重载。更重要的是,它会检查基类虚函数和派生类中重载函数的签名不匹配问题。如果签名不匹配ÿ…

平头哥发布一站式芯片设计平台“无剑”,芯片设计成本降低50%
导读:8 月 29 日,在上海举行的世界人工智能大会上,阿里巴巴旗下半导体公司平头哥发布 SoC 芯片平台“无剑”。无剑是面向 AIoT 时代的一站式芯片设计平台,提供集芯片架构、基础软件、算法与开发工具于一体的整体解决方案ÿ…

Windows XP下,JDK环境变量配置
2019独角兽企业重金招聘Python工程师标准>>> 1.安装JDK,安装过程中可以自定义安装目录等信息,例如我们选择安装目录为D:\java\jdk1.5.0_08; 2.安装完成后,右击“我的电脑”,点击“属性”; 3.选择…

Markdown语法简介
Markdown是一种方便记忆、书写的纯文本标记语言,用户可以使用这些标记符号以最小的输入代价生成极富表现力的文档。它目标是实现易读易写。Markdown的语法全由一些符号所组成。Markdown语法的目标是成为一种适用于网络的书写语言。 Markdown优点:纯文本…

吴恩达:AI未来将呈现四大发展趋势
作者 | 夕颜出品 | AI科技大本营(ID:rgznai100)导读:8 月 30 日,世界人工智能大会精彩继续。在今天的全球工业智能峰会上,Landing.AI 创始人及首席执行官吴恩达来到现场,做了题为《人工智能是新电力》的演讲…

嵌入式课程安排 嵌入式培训课程大纲参考
嵌入式是一门综合性的学科,现在学习嵌入式开发不是单纯局限于单片机或者Linux,嵌入式课程中包含着非常多的内容。以粤嵌嵌入式课程进行参考,看看我们要学习嵌入式的话,要掌握哪些必备的技能。嵌入式课程安排包含:1、入…

Linux网站架构系列之Apache----进阶篇
本篇博文为Linux网站架构系列之apache的第二篇,我将带大家一起学习apache的编译参数,目录结构和配置文件等方面的知识,实现对apache服务的进一步掌握,并使之能更好的应用到生产实战中去。一、编译参数在上篇的apache部署中&#x…

仅用10天设计的JavaScript,凭什么成为程序员最受欢迎的编程语言?
导语:在这个世纪之交诞生的 JavaScript,没人想到会发展为当今世界上最流行的语言之一。它不够成熟,不够严肃,甚至连名字都是模仿的 Java。那么,JavaScript 的成功是依靠运气和完美时机的侥幸吗?其实不然——…

C++11中= delete;的使用
C11中,对于deleted函数,编译器会对其禁用,从而避免某些非法的函数调用或者类型转换,从而提高代码的安全性。 对于 C 的类,如果程序员没有为其定义特殊成员函数,那么在需要用到某个特殊成员函数的时候&…

vue 使用scss
使用vue-cli模板创建的项目中,使用scss步骤 1. cmd命令: cnpm install sass-loader --save-devcnpm install node-sass --sava-dev2.查看package.json文件中是否已自动添加以下信息 3. 转载于:https://www.cnblogs.com/duanzhenzhen/p/10453495.html

EBS form日历可选范围设置(calendar.setup )介绍
Calendar是Template提供给我们的standard object.可以使我们方便的为日期型字段提供日期的选择列表.form中设置日历方法:1. 为日期型字段指定LOV(ENABLE_LIST_LAMP)2. 在字段的KEY–LISTVAL事件中编写代码:Calendar.showCalendar Package包含如下几个Procedure:1. Calendar.sho…

人工智能对地球环境科学的推进
一项德国耶拿[1]和汉堡[2]科学家在《自然》杂志发起的研究表明,人工智能可以有效地推进我们对于地球气候系统的理解。特别是在当前深度学习的潜力还未被完全开发的情况下。在人工智能的帮助下一些复杂的动态环境,如飓风,森林火灾,…

从概念到应用,终于有人把数据挖掘讲明白了
作者:陈封能(Pang-Ning Tan)、迈克尔斯坦巴赫(Michael Steinbach)等来源 | 大数据(ID: hzdashuju)【导语】数据采集和存储技术的迅速发展,加之数据生成与传播的便捷性&am…

C++11中default的使用
在C11中,对于defaulted函数,编译器会为其自动生成默认的函数定义体,从而获得更高的代码执行效率,也可免除程序员手动定义该函数的工作量。 C的类有四类特殊成员函数,它们分别是:默认构造函数、析构函数、拷…

Android开发:setAlpha()方法和常用RGB颜色表----颜色, r g b分量数值(int), 16进制表示 一一对应...
杂家前文Android颜色对照表只有颜色和十六进制,有时候需要设置r g b分量的int值,如paint.setARGB(255, 127, 255, 212);就需要自己计算下分量的各个值。这里提供一个带有r g b分量的int型的颜色表。注意paint.setAlpha()及paint.setARGB(&…

【redis】c/c++操作redis(对于hiredis的封装)
前言 最近一直在学习redis,通过c/cpp来执行redis命令,使用的是hiredis客户端来实现的。 先简单贴一下代码 头文件 #include <vector> #include <string> #include <hiredis/hiredis.h> typedef enum en_redisResultType {redis_reply_…
OpenCV代码提取:transpose函数的实现
OpenCV中的transpose函数实现图像转置,公式为:目前fbc_cv库中也实现了transpose函数,支持多通道,uchar和float两种数据类型,经测试,与OpenCV3.1结果完全一致。实现代码transpose.hpp:// fbc_cv …

只给测试集不给训练集,要怎么做自己的物体检测器?
9 月5 日,下周四,大家期待已久的由《动手学深度学习》作者,亚马逊首席科学家亲自带领的「深度学习实训营」就要在北京开营了。今天,李沐已经把这次深度学习实训营白天的教学内容和代码上传到 Gituhub 和 D2L.ai 网站了,…

MYSQL忘记登录密码
1、关闭Mysql: 如果 MySQL 正在运行,首先杀之 killall -TERM mysqld 2、另外的方法启动 MySQL :bin/safe_mysqld --skip-grant-tables 3、可以不需要密码就进入 MySQL 了。 然后就是 >use mysql>update user set passwordpassword(&qu…
OpenCV代码提取:flip函数的实现
OpenCV中实现图像翻转的函数flip,公式为:目前fbc_cv库中也实现了flip函数,支持多通道,uchar和float两种数据类型,经测试,与OpenCV3.1结果完全一致。实现代码flip.hpp:// fbc_cv is free softwar…

NLP这两年:15个预训练模型对比分析与剖析
作者 | JayLou来源 | 知乎前言在之前写过的《NLP的游戏规则从此改写?从word2vec, ELMo到BERT》一文中,介绍了从word2vec到ELMo再到BERT的发展路径。而在BERT出现之后的这大半年的时间里,模型预训练的方法又被Google、Facebook、微软、百度、O…

大三下学期第一周总结
本周以是开学第一周了,在生活方面,生活琐事确实变多了起来。每天上课,看着老师熟悉的面庞,如履春风。感觉学习没有那么多的陌生恐惧。学习是一方面,身体锻炼不能落下。一周至少保证三小时及其以上的运动。身体是革命的…