当前位置: 首页 > 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…...

BCS 2025|百度副总裁陈洋:智能体在安全领域的应用实践

6月5日&#xff0c;2025全球数字经济大会数字安全主论坛暨北京网络安全大会在国家会议中心隆重开幕。百度副总裁陈洋受邀出席&#xff0c;并作《智能体在安全领域的应用实践》主题演讲&#xff0c;分享了在智能体在安全领域的突破性实践。他指出&#xff0c;百度通过将安全能力…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

AI病理诊断七剑下天山,医疗未来触手可及

一、病理诊断困局&#xff1a;刀尖上的医学艺术 1.1 金标准背后的隐痛 病理诊断被誉为"诊断的诊断"&#xff0c;医生需通过显微镜观察组织切片&#xff0c;在细胞迷宫中捕捉癌变信号。某省病理质控报告显示&#xff0c;基层医院误诊率达12%-15%&#xff0c;专家会诊…...

Kafka入门-生产者

生产者 生产者发送流程&#xff1a; 延迟时间为0ms时&#xff0c;也就意味着每当有数据就会直接发送 异步发送API 异步发送和同步发送的不同在于&#xff1a;异步发送不需要等待结果&#xff0c;同步发送必须等待结果才能进行下一步发送。 普通异步发送 首先导入所需的k…...

Redis:现代应用开发的高效内存数据存储利器

一、Redis的起源与发展 Redis最初由意大利程序员Salvatore Sanfilippo在2009年开发&#xff0c;其初衷是为了满足他自己的一个项目需求&#xff0c;即需要一个高性能的键值存储系统来解决传统数据库在高并发场景下的性能瓶颈。随着项目的开源&#xff0c;Redis凭借其简单易用、…...

深度剖析 DeepSeek 开源模型部署与应用:策略、权衡与未来走向

在人工智能技术呈指数级发展的当下&#xff0c;大模型已然成为推动各行业变革的核心驱动力。DeepSeek 开源模型以其卓越的性能和灵活的开源特性&#xff0c;吸引了众多企业与开发者的目光。如何高效且合理地部署与运用 DeepSeek 模型&#xff0c;成为释放其巨大潜力的关键所在&…...

鸿蒙(HarmonyOS5)实现跳一跳小游戏

下面我将介绍如何使用鸿蒙的ArkUI框架&#xff0c;实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...

WEB3全栈开发——面试专业技能点P4数据库

一、mysql2 原生驱动及其连接机制 概念介绍 mysql2 是 Node.js 环境中广泛使用的 MySQL 客户端库&#xff0c;基于 mysql 库改进而来&#xff0c;具有更好的性能、Promise 支持、流式查询、二进制数据处理能力等。 主要特点&#xff1a; 支持 Promise / async-await&#xf…...

python打卡第47天

昨天代码中注意力热图的部分顺移至今天 知识点回顾&#xff1a; 热力图 作业&#xff1a;对比不同卷积层热图可视化的结果 def visualize_attention_map(model, test_loader, device, class_names, num_samples3):"""可视化模型的注意力热力图&#xff0c;展示模…...

用js实现常见排序算法

以下是几种常见排序算法的 JS实现&#xff0c;包括选择排序、冒泡排序、插入排序、快速排序和归并排序&#xff0c;以及每种算法的特点和复杂度分析 1. 选择排序&#xff08;Selection Sort&#xff09; 核心思想&#xff1a;每次从未排序部分选择最小元素&#xff0c;与未排…...