当前位置: 首页 > news >正文

C++相关闲碎记录(2)

1、误用shared_ptr

int* p = new int;
shared_ptr<int> sp1(p);
shared_ptr<int> sp2(p);  //error 
// 通过原始指针两次创建shared_ptr是错误的shared_ptr<int> sp1(new int);
shared_ptr<int> sp2(sp1);  //ok

如果对C++相关闲碎记录(1)中记录的shared_ptr的使用例子修改为如下:父类添加孩子的shared_ptr时调用下面这个函数来实现,同样会出现问题:

class Person {
public:string name;shared_ptr<Person> mother;shared_ptr<Person> father;vector<weak_ptr<Person>> kids;   //使用weak_ptrPerson(const string& n, shared_ptr<Person> m = nullptr,shared_ptr<Person> f = nullptr) :name(n), mother(m), father(f) {}~Person() {cout << "delete " << name << endl;}void setParentAndTheirKids(shared_ptr<Person> m = nullptr, shared_ptr<Person> f = nullptr) {mother = m;father = f;if (m != nullptr) {m->kids.push_back(shared_ptr<Person>(this));  //error// 为什么这里会报错,因为this所指的对象已经有一个shared_ptr了,再通过这种方式创建shared_ptr就会报错,因为会重新开启一个拥有者团队}if (f != nullptr){f->kids.push_back(shared_ptr<Person>(this)); //error}}
};shared_ptr<Person> initFamily(const string& name) {shared_ptr<Person> mom(new Person(name + "'s mom"));shared_ptr<Person> dad(new Person(name + "'s dad"));shared_ptr<Person> kid(new Person(name));kid->setParentAndTheirKids(mom, dad);return kid;
}

使用enable_shared_from_this<Person>

#include <iostream>
#include <string>
#include <vector>
#include <memory>
using namespace std;class Person : public enable_shared_from_this<Person> {public:string name;shared_ptr<Person> mother;shared_ptr<Person> father;vector<weak_ptr<Person>> kids;  // weak pointer !!!Person (const string& n): name(n) {}void setParentsAndTheirKids (shared_ptr<Person> m = nullptr,shared_ptr<Person> f = nullptr) {mother = m;father = f;if (m != nullptr) {m->kids.push_back(shared_from_this());}if (f != nullptr) {f->kids.push_back(shared_from_this());}}~Person() {cout << "delete " << name << endl;}
};shared_ptr<Person> initFamily (const string& name)
{shared_ptr<Person> mom(new Person(name+"'s mom")); shared_ptr<Person> dad(new Person(name+"'s dad")); shared_ptr<Person> kid(new Person(name)); kid->setParentsAndTheirKids(mom,dad); return kid;
}int main()
{shared_ptr<Person> p = initFamily("nico");cout << "nico's family exists" << endl;cout << "- nico is shared " << p.use_count() << " times" << endl;cout << "- name of 1st kid of nico's mom: " << p->mother->kids[0].lock()->name << endl;p = initFamily("jim");cout << "jim's family exists" << endl;
}

shared_ptr各种操作:

 

shared_ptr<void> sp(new int);
shared_ptr<int>(static_cast<int*>(sp.get()))   //error
static_pointer_cast<int*>(sp)std::unique_ptr<int> up = new int;  //error
std::unique_ptr<int> up(new int); // ok

unique_ptr不必一定拥有对象,也可以是empty。

std::unique_ptr<std::string> up;
可以赋值为nullptr或者调用reset
up = nullptr;
up.reset();

unique_ptr可以调用release(),释放所拥有的对象,并将所有权交给调用者。

std::unique_ptr<std::string> up(new std::string("nico"));
std::string* sp = up.release();

2、转移unique_ptr的拥有权

std::string* sp = new std::string("hello");
std::unique_ptr<std::string> up1(sp);
std::unique_ptr<std::string) up2(sp);  //error  up1 and up2 own same datastd::unique_ptr<std::string[]> up(new std::string[10]);  //ok
此偏特化不再提供操作符*和->,而提供[]操作符,访问array中的一个对象时,使用[]std::cout << *up << std::endl; //error
std::cout << up[0] << std::endl;  //ok

指定自定义删除器:通过类的方式指定

class ClassADeleter {
public:void operator() (ClassA* p) {std::cout << "call delete for ClassA object" << std::endl;delete p;}
};std::unique_ptr<ClassA, ClassADeleter> up(new ClassA());

如果是个函数或者lambda,必须声明deleter的类型为void(*)(T*)或者std::function<void(T*)>,要不就使用decltype,例如要为array of int指定自己的deleter,并以lambda形式呈现:

std::unique_ptr<int, void(*)(int*)> up(new int[10], [](int* p) {delete []p;});std::unique_ptr<int, std::function<void(int*)>> up(new int[10], [](int* p) {delete []p;});或者
auto l = [](int*) {delete [] p;};
std::unique_ptr<int, decltype(l)>> up(new int[10], l);

 为了避免传递function pointer 或者lambda 时必须指明deleter的类型,你可以使用alias template

template<typename T>
using uniquePtr = std::unique_ptr<T, void(*)(T*)>;uniquePtr<int> up(new int[10], [](int* p) {delete [] p;});

unique_ptr各种操作:

 3、numeric_limits<>

#include <iostream>
#include <limits>
#include <string>
using namespace std;int main()
{// use textual representation for boolcout << boolalpha;// print maximum of integral typescout << "max(short): " << numeric_limits<short>::max() << endl;cout << "max(int):   " << numeric_limits<int>::max() << endl;cout << "max(long):  " << numeric_limits<long>::max() << endl;cout << endl;// print maximum of floating-point typescout << "max(float):       "<< numeric_limits<float>::max() << endl;cout << "max(double):      "<< numeric_limits<double>::max() << endl;cout << "max(long double): "<< numeric_limits<long double>::max() << endl;cout << endl;// print whether char is signedcout << "is_signed(char): "<< numeric_limits<char>::is_signed << endl;cout << endl;// print whether numeric limits for type string existcout << "is_specialized(string): "<< numeric_limits<string>::is_specialized << endl;
}

 4、type trait的使用

#include <iostream>
#include <limits>
#include <string>
using namespace std;// type trait
template <typename T>
void foo_impl(T val, true_type) {std::cout << "Integer" << std::endl;
}template <typename T>
void foo_impl(T val, false_type) {std::cout << "not Integer" << std::endl;
}template <typename T>
void foo(T val) {foo_impl(val, std::is_integral<T>());
}int main()
{double d_a = 1.2;long long int ll_b = 33333;foo(d_a);foo(ll_b);
}输出:
not Integer
Integer
类型判断工具

 用以阐明class细节的trait
#include <iostream>
#include <limits>
#include <type_traits>
using namespace std;int main()
{std::cout << boolalpha << is_const<int>::value << endl;                    //falsestd::cout << boolalpha << is_const<const volatile int>::value << endl;     //truestd::cout << boolalpha << is_const<int* const>::value << endl;             //truestd::cout << boolalpha << is_const<const int*>::value << endl;             //falsestd::cout << boolalpha << is_const<const int&>::value << endl;             //falsestd::cout << boolalpha << is_const<int[3]>::value << endl;                 //falsestd::cout << boolalpha << is_const<const int[3]>::value << endl;           //truestd::cout << boolalpha << is_const<int[]>::value << endl;                  //falsestd::cout << boolalpha << is_const<const int[]>::value << endl;            //truereturn 0;
}

 指向const类型的非常量指针或者引用,并不是一个常量,尽管内含元素是常量,例如const int* 并不是常量,只是描述指针所指向的这个变量是常量类型,但是指针本身可以重新指向新的变量。

用以检测copy和move语义的那些个trait,只检测是否相应的表达式为可能,例如一个带有copy构造函数的(接受常量实参)但没有move构造函数的类型,仍然是move constructible.

用以检验类型关系的trait 

 

int main()
{std::cout << boolalpha << is_assignable<int, int>::value << endl;                               //falsestd::cout << boolalpha << is_assignable<int&, int>::value << endl;                              //truestd::cout << boolalpha << is_assignable<int&&, int>::value << endl;                             //falsestd::cout << boolalpha << is_assignable<long&, int>::value << endl;                             //truestd::cout << boolalpha << is_assignable<int&, void*>::value << endl;                            //falsestd::cout << boolalpha << is_assignable<void*, int>::value << endl;                             //falsestd::cout << boolalpha << is_assignable<const char*, std::string>::value << endl;               //falsestd::cout << boolalpha << is_assignable<std::string, const char*>::value << endl;               //truestd::cout << boolalpha << is_constructible<int>::value << endl;                                 //truestd::cout << boolalpha << is_constructible<int, int>::value << endl;                            //truestd::cout << boolalpha << is_constructible<long, int>::value << endl;                           //truestd::cout << boolalpha << is_constructible<int, void*>::value << endl;                          //falsestd::cout << boolalpha << is_constructible<void*, int>::value << endl;                          //falsestd::cout << boolalpha << is_constructible<const char*, std::string>::value << endl;            //falsestd::cout << boolalpha << is_constructible<std::string, const char*>::value << endl;            //truestd::cout << boolalpha << is_constructible<std::string, const char*, int, int>::value << endl;  //truereturn 0;
}

5、类型修饰符

#include <iostream>
#include <limits>
#include <type_traits>
#include <typeinfo>
#include <cxxabi.h>
using namespace std;int main()
{typedef int T;typedef add_const<T>::type A;                //const inttypedef add_lvalue_reference<T>::type B;     //int&typedef add_rvalue_reference<T>::type C;     //int&&typedef add_pointer<T>::type D;              //int*typedef make_signed<T>::type E;              //inttypedef make_unsigned<T>::type F;            //unsigned inttypedef remove_const<T>::type G;             //inttypedef remove_reference<T>::type H;         //inttypedef remove_pointer<T>::type I;           //intstd::cout << boolalpha << is_const<A>::value << std::endl;// 查看完整类型std::cout << abi::__cxa_demangle(typeid(A).name(),0,0,0 ) << std::endl;std::cout << typeid(B).name() << std::endl;std::cout << "A is same const int ?" << boolalpha << is_same<const int, A>::value << std::endl;std::cout << "B is same int& ?" << boolalpha << is_same<int&, B>::value << std::endl;typedef const int& T1;typedef add_const<T1>::type A1;                  // const int&typedef add_lvalue_reference<T1>::type B1;       //const int&typedef add_rvalue_reference<T1>::type C1;       //const int& (yes, lvalue remains lvalue)typedef add_pointer<T1>::type D1;                //const int*// typedef make_signed<T1>::type E1;             //undefined behavior// typedef make_unsigned<T1>::type F1;           //undefined bahaviortypedef remove_const<T1>::type G1;               //const int&typedef remove_reference<T1>::type H1;           //const inttypedef remove_pointer<T1>::type I1;             //cosnt int&std::cout << "A1 is same const int& ?" << boolalpha << is_same<const int&, A1>::value << std::endl;std::cout << is_const<A1>::value << std::endl;std::cout << "G1 is same const int& ?" << boolalpha << is_same<const int&, G1>::value << std::endl;return 0;
}

 指向某常量类型的reference本身并不是常量,所以不可以移除const,add_pointer<>必然包含使用remove_reference<>,然而make_signed<>和make_unsigned<>必须是整型,枚举型,bool除外,所以传入引用会导致不明确的行为。add_lvalue_reference<>把一个rvalue reference转换为一个lvalue reference,然而add_rvalue_reference<>并不会把一个lvalue reference转换为一个rvalue reference.

6、其他type trait 

#include <iostream>
#include <limits>
#include <type_traits>
#include <typeinfo>
#include <cxxabi.h>
using namespace std;int main()
{std::cout << rank<int>::value << std::endl;                   //0std::cout << rank<int[]>::value << std::endl;                 //1std::cout << rank<int[3]>::value << std::endl;                //1std::cout << rank<int[][4]>::value << std::endl;              //2std::cout << rank<int[3][4]>::value << std::endl;             //2std::cout << extent<int>::value << std::endl;                 //0std::cout << extent<int[]>::value << std::endl;               //0std::cout << extent<int[3]>::value << std::endl;              //3std::cout << extent<int[][4]>::value << std::endl;            //0std::cout << extent<int[3][3]>::value << std::endl;           //3std::cout << extent<int[][3], 1>::value << std::endl;         //3std::cout << extent<int[5][6], 1>::value << std::endl;        //6std::cout << extent<int[3][4], 2>::value << std::endl;        //0typedef remove_extent<int>::type A;                           //inttypedef remove_extent<int[]>::type B;                         //inttypedef remove_extent<int[3]>::type C;                        //inttypedef remove_extent<int[][8]>::type D;                      //int[8]typedef remove_extent<int[5][6]>::type E;                     //int[7]typedef remove_all_extents<int>::type F;                      //inttypedef remove_all_extents<int>::type G;                      //inttypedef remove_all_extents<int[]>::type H;                    //inttypedef remove_all_extents<int[5]>::type I;                   //inttypedef remove_all_extents<int[][9]>::type J;                 //inttypedef remove_all_extents<int[5][8]>::type K;                //intreturn 0;
}

相关文章:

C++相关闲碎记录(2)

1、误用shared_ptr int* p new int; shared_ptr<int> sp1(p); shared_ptr<int> sp2(p); //error // 通过原始指针两次创建shared_ptr是错误的shared_ptr<int> sp1(new int); shared_ptr<int> sp2(sp1); //ok 如果对C相关闲碎记录(1)中记录的shar…...

如何快速搭建一个大模型?简单的UI实现

&#x1f525;博客主页&#xff1a;真的睡不醒 &#x1f680;系列专栏&#xff1a;深度学习环境搭建、环境配置问题解决、自然语言处理、语音信号处理、项目开发 &#x1f498;每日语录&#xff1a;相信自己&#xff0c;一路风景一路歌&#xff0c;人生之美&#xff0c;正在于…...

国家开放大学 平时作业 测试题 训练

试卷代号&#xff1a;1340 古代小说戏曲专题 参考试题&#xff08;开卷&#xff09; 一、选择&#xff08;每题1分&#xff0c;共10分&#xff09; 1.下列作品中属于唐传奇的是( )。 A.《公孙九娘》 B.《观音作别》 C《碾玉观音》 …...

后端防止重复提交相同数据处理方式(Redis)

使用AOP注解处理接口幂等性&#xff0c;默认禁止同一用户在上次提交未果后10秒内又重复提交 在原先的sameUrlData的注解上进行了copy新建优化&#xff0c;使用redis去setnx的参数视项目使用点而调整&#xff0c;不一定是每个项目都适合这种取参形式。 源码如下: package com…...

最小栈[中等]

优质博文&#xff1a;IT-BLOG-CN 一、题目 设计一个支持push&#xff0c;pop&#xff0c;top操作&#xff0c;并能在常数时间内检索到最小元素的栈。 实现MinStack类: MinStack()初始化堆栈对象。 void push(int val)将元素val推入堆栈。 void pop()删除堆栈顶部的元素。 in…...

Oracle(2-9) Oracle Recovery Manager Overview and Configuration

文章目录 一、基础知识1、User Backup VS RMAN2、Restoring &Recovering DB 还原&恢复数据库3、Recovery Manager Features 管理恢复功能4、RMAN Components RMAN组件5、Repository1: Control File 存储库1:控制文件6、Channel Allocation 通道道分配7、Media Manageme…...

滑动验证码

先上图 代码&#xff1a; <!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>滑动验证码</title><style>* {margin: 0;padding: 0;}.box {position: relative;width: 375px;margin: 100px a…...

数据爬取+可视化实战_告白气球_词云展示----酷狗音乐

一、前言 歌词上做文本分析&#xff0c;数据存储在网页上&#xff0c;需要爬取数据下来&#xff0c;词云展示在工作中也变得日益重要&#xff0c;接下来将数据爬虫与可视化结合起来&#xff0c;做个词云展示案例。 二、代码 # -*- coding:utf-8 -*- # 酷狗音乐 通过获取每首歌…...

rkmedia_vi_get_frame_test.c 代码解析

使用示例&#xff1a; 录像&#xff1a; rkmedia_vi_get_frame_test -a /etc/iqfiles/ -I 1 -o 1080.nv12 然后用yuvplayer.exe可以播放。 录像10帧&#xff1a; rkmedia_vi_get_frame_test -a /etc/iqfiles/ -I 1 -o 1080.nv12 -c 10 解析代码&#xff1a; #include <as…...

探究Kafka原理-3.生产者消费者API原理解析

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱吃芝士的土豆倪&#xff0c;24届校招生Java选手&#xff0c;很高兴认识大家&#x1f4d5;系列专栏&#xff1a;Spring源码、JUC源码、Kafka原理&#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44…...

Linux系统iptables扩展

目录 一. iptables规则保存 1. 导出规则保存 2. 自动重载规则 ①. 当前用户生效 ②. 全局生效 二. 自定义链 1. 新建自定义链 2. 重命名自定义链 3. 添加自定义链规则 4. 调用自定义链规则 5. 删除自定义链 三. NAT 1. SNAT 2. DNAT 3. 实验 ①. 实验要求 ②. …...

Openwrt 系统安装 插件名称与中文释义

系统镜像 当时是去官网找对应的&#xff0c;但是作为门外汉&#xff0c;想简单&#xff0c;可以试试这个网站 插件 OpenWrt/Lede全部插件列表功能注释...

[原创]Delphi的SizeOf(), Length(), 动态数组, 静态数组的关系.

[简介] 常用网名: 猪头三 出生日期: 1981.XX.XXQQ: 643439947 个人网站: 80x86汇编小站 https://www.x86asm.org 编程生涯: 2001年~至今[共22年] 职业生涯: 20年 开发语言: C/C、80x86ASM、PHP、Perl、Objective-C、Object Pascal、C#、Python 开发工具: Visual Studio、Delphi…...

C++(20):bind_front

C(11)&#xff1a;bind_c11 bind_风静如云的博客-CSDN博客 提供了方法来绑定函数参数的方法。 C20提供了bind_front用于简化这个绑定。 #include <iostream> #include <functional> using namespace std;void func1(int d1, int d2) {cout<<__func__<&l…...

【spring】bean的后处理器

目录 一、作用二、常见的bean后处理器2.1 AutowiredAnnotationBeanPostProcessor2.1.1 说明2.1.2 代码示例2.1.3 截图示例 2.2 CommonAnnotationBeanPostProcessor2.2.1 说明2.2.2 代码示例2.2.3 截图示例 2.3 ConfigurationPropertiesBindingPostProcessor2.3.1 说明2.3.2 代码…...

Centos7安装docker、java、python环境

文章目录 前言一、docker的安装二、docker-compose的安装三、安装python3和配置pip3配置python软链接&#xff08;关键&#xff09; 四、Centos 7.6操作系统安装JAVA环境 前言 每次vps安装docker都要看网上的文章&#xff0c;而且都非常坑&#xff0c;方法千奇百怪&#xff0c…...

简单小结类与对象

/*** Description 简单小结类与对象*/ package com.oop;import com.oop.demo03.Pet;public class Application {public static void main(String[] args) {/*1.类与对象类是一个模版&#xff1a;抽象&#xff0c;对象是一个具体的实例2.方法定义、调用&#xff01;3.对象的引用…...

ABAP 如何获取内表行的索引值(index) ?

获取索引值 在ABAP中&#xff0c;如果需要获取一个内表中某条记录的索引&#xff08;index&#xff09;&#xff0c;可以使用 READ TABLE 语句。在 READ TABLE 语句后面的 WITH KEY 子句可以指定搜索条件&#xff0c;如果找到了匹配的记录&#xff0c;系统字段 SY-TABIX 将保存…...

ESP32-Web-Server编程- 使用表格(Table)实时显示设备信息

ESP32-Web-Server编程- 使用表格&#xff08;Table&#xff09;实时显示设备信息 概述 上节讲述了通过 Server-Sent Events&#xff08;以下简称 SSE&#xff09; 实现在网页实时更新 ESP32 Web 服务器的传感器数据。 本节书接上会&#xff0c;继续使用 SSE 机制在网页实时显…...

vue3 Hooks函数使用及常用utils封装

hooks 是什么 vue3使用了composition API&#xff0c;我们可自定义封装hooks&#xff0c;达到复用&#xff0c;在Vue2中采取的mixins&#xff0c;对mixins而言&#xff0c; hooks更清楚复用功能代码的来源, 更清晰易懂。 简单来说&#xff1a;hooks 就是函数的一种写法&#xf…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

Swift 协议扩展精进之路:解决 CoreData 托管实体子类的类型不匹配问题(下)

概述 在 Swift 开发语言中&#xff0c;各位秃头小码农们可以充分利用语法本身所带来的便利去劈荆斩棘。我们还可以恣意利用泛型、协议关联类型和协议扩展来进一步简化和优化我们复杂的代码需求。 不过&#xff0c;在涉及到多个子类派生于基类进行多态模拟的场景下&#xff0c;…...

c++ 面试题(1)-----深度优先搜索(DFS)实现

操作系统&#xff1a;ubuntu22.04 IDE:Visual Studio Code 编程语言&#xff1a;C11 题目描述 地上有一个 m 行 n 列的方格&#xff0c;从坐标 [0,0] 起始。一个机器人可以从某一格移动到上下左右四个格子&#xff0c;但不能进入行坐标和列坐标的数位之和大于 k 的格子。 例…...

多模态大语言模型arxiv论文略读(108)

CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文标题&#xff1a;CROME: Cross-Modal Adapters for Efficient Multimodal LLM ➡️ 论文作者&#xff1a;Sayna Ebrahimi, Sercan O. Arik, Tejas Nama, Tomas Pfister ➡️ 研究机构: Google Cloud AI Re…...

OPenCV CUDA模块图像处理-----对图像执行 均值漂移滤波(Mean Shift Filtering)函数meanShiftFiltering()

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 在 GPU 上对图像执行 均值漂移滤波&#xff08;Mean Shift Filtering&#xff09;&#xff0c;用于图像分割或平滑处理。 该函数将输入图像中的…...

【C++特殊工具与技术】优化内存分配(一):C++中的内存分配

目录 一、C 内存的基本概念​ 1.1 内存的物理与逻辑结构​ 1.2 C 程序的内存区域划分​ 二、栈内存分配​ 2.1 栈内存的特点​ 2.2 栈内存分配示例​ 三、堆内存分配​ 3.1 new和delete操作符​ 4.2 内存泄漏与悬空指针问题​ 4.3 new和delete的重载​ 四、智能指针…...

Caliper 负载(Workload)详细解析

Caliper 负载(Workload)详细解析 负载(Workload)是 Caliper 性能测试的核心部分,它定义了测试期间要执行的具体合约调用行为和交易模式。下面我将全面深入地讲解负载的各个方面。 一、负载模块基本结构 一个典型的负载模块(如 workload.js)包含以下基本结构: use strict;/…...

react菜单,动态绑定点击事件,菜单分离出去单独的js文件,Ant框架

1、菜单文件treeTop.js // 顶部菜单 import { AppstoreOutlined, SettingOutlined } from ant-design/icons; // 定义菜单项数据 const treeTop [{label: Docker管理,key: 1,icon: <AppstoreOutlined />,url:"/docker/index"},{label: 权限管理,key: 2,icon:…...

【Java】Ajax 技术详解

文章目录 1. Filter 过滤器1.1 Filter 概述1.2 Filter 快速入门开发步骤:1.3 Filter 执行流程1.4 Filter 拦截路径配置1.5 过滤器链2. Listener 监听器2.1 Listener 概述2.2 ServletContextListener3. Ajax 技术3.1 Ajax 概述3.2 Ajax 快速入门服务端实现:客户端实现:4. Axi…...

英国云服务器上安装宝塔面板(BT Panel)

在英国云服务器上安装宝塔面板&#xff08;BT Panel&#xff09; 是完全可行的&#xff0c;尤其适合需要远程管理Linux服务器、快速部署网站、数据库、FTP、SSL证书等服务的用户。宝塔面板以其可视化操作界面和强大的功能广受国内用户欢迎&#xff0c;虽然官方主要面向中国大陆…...