C++
文章平均质量分 54
C++学习
雪*夹雨夹*雪
这个作者很懒,什么都没留下…
展开
-
C++面试关于类的一些常见问题
什么是虚函数?什么是纯虚函数?虚函数:被 virtual 关键字修饰的成员函数,就是虚函数。#include <iostream>using namespace std;class A{public: virtual void v_fun() // 虚函数 { cout << "A::v_fun()" << endl; }};class B : public A{public: void v_fun()转载 2022-05-28 13:15:45 · 232 阅读 · 0 评论 -
C++ define和const , typedef,inline 的区别
define 和 typedef 的区别原理:#define 作为预处理指令,在编译预处理时进行替换操作,不作正确性检查,只有在编译已被展开的源程序时才会发现可能的错误并报错。typedef 是关键字,在编译时处理,有类型检查功能,用来给一个已经存在的类型一个别名,但不能在一个函数定义里面使用 typedef 。功能:typedef 用来定义类型的别名,方便使用。#define 不仅可以为类型取别名,还可以定义常量、变量、编译开关等。作用域:#define 没有作用域的限制,只要是之前预定义过的宏,在原创 2022-05-28 12:20:36 · 220 阅读 · 0 评论 -
c++/c程序编译过程
编译过程分为四个过程:编译(编译预处理、编译、优化),汇编,链接。编译预处理:处理以 # 开头的指令;编译、优化:将源码 .cpp 文件翻译成 .s 汇编代码;汇编:将汇编代码 .s 翻译成机器指令 .o 文件;链接:汇编程序生成的目标文件,即 .o 文件,并不会立即执行,因为可能会出现:.cpp 文件中的函数引用了另一个 .cpp 文件中定义的符号或者调用了某个库文件中的函数。那链接的目的就是将这些文件对应的目标文件连接成一个整体,从而生成可执行的程序 .exe 文件。链接分为两种:静态链接:代码原创 2022-05-14 23:16:37 · 172 阅读 · 0 评论 -
查找数组中的第K个最大元素或者数组中最大的k个元素,C++解法
题目给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。示例 1:输入: [3,2,1,5,6,4] 和 k = 2输出: 5示例 2:输入: [3,2,3,1,2,4,5,5,6] 和 k = 4输出: 4题解思路是维护一个长度为k的最小堆,堆顶是这个堆中的最小的元素;对数组的每一个元素进行遍历,如果堆元素小于k或者当前遍历的元素大于堆顶元素,那就让当前元素入堆,然后再弹出一个最小的元素原创 2022-05-02 16:26:33 · 1362 阅读 · 0 评论 -
C++标准中的左值和右值
我们知道,C++ 里有左值和右值。但是标准里的定义实际更复杂,规定了下面这些值类别(value categories):它们的释义如下:lvalue: 左值,是通常可以放在等号左边的表达式rvalue:右值,是通常只能放在等号右边的表达式glvalue:generalized lvalue,广义左值xvalue: expiring lvalue,将亡值prvalue:pure rvalue,纯右值我们暂且抛开这些概念,只看其中两个:lvalue 和 prvalue。左值 lvalue 是原创 2022-03-02 00:02:45 · 661 阅读 · 0 评论 -
C++ 为什么要使用weak_ptr及其使用场景
我们知道std::shared_ptr会共享对象的所有权,但是有一些场景如果有一个像std::shared_ptr但是又不参与资源所有权共享的指针是很方便的。换句话说,是一个类似std::shared_ptr但不影响对象引用计数的指针。不参与资源所有权就意味着不会对资源的生命周期产生影响,有利于对象之间的解耦。举个一个不太恰当的例子,A和B相互加了微信,假设我们用一个指针来指向自己的微信朋友,如果是shared_ptr,那么A和B的生命周期是相互影响的,而实际上我们并不希望这种强绑定,比如假设B注销了账户,原创 2022-03-01 00:35:46 · 1645 阅读 · 0 评论 -
C++:enable_shared_from_this和shared_from_this的作用
shared_from_this的作用是返回一个指向this指针的有效shared_ptr.class Y: public enable_shared_from_this<Y>{public: shared_ptr<Y> f() { return shared_from_this(); }}int main(){ shared_ptr<Y> p(new Y); shared_ptr<Y>原创 2022-02-26 23:18:54 · 1429 阅读 · 0 评论 -
C++:shared_ptr内存布局
使用shared_ptr构造的布局:使用make_shared的布局:原创 2022-02-26 22:14:02 · 843 阅读 · 0 评论 -
C++ std::shared_ptr:为什么使用shared_ptr及其一些问题
C++11中的std::shared_ptr将两者组合了起来。一个通过std::shared_ptr访问的对象其生命周期由指向它的指针们共享所有权(shared ownership)。没有特定的std::shared_ptr拥有该对象。相反,所有指向它的std::shared_ptr都能相互合作确保在它不再使用的那个点进行析构。当最后一个std::shared_ptr到达那个点,std::shared_ptr会销毁它所指向的对象。就垃圾回收来说,客户端不需要关心指向对象的生命周期,而对象的析构是确定性的。原创 2022-02-20 23:19:41 · 2888 阅读 · 0 评论 -
C++ std::condition_variable::notify_one()与notify_all()
std::condition_variable的成员函数notify_one()与notify_all()是用来唤醒阻塞在wait()的线程。假如有多个线程调用condition_variable::wait()陷入休眠之后。condition_variable的实现中有一个等待队列来保存堵塞在它之上的线程。当其他线程调用notify_one()时,只唤醒等待队列中的第一个线程;其余的线程不会被唤醒,需要等待再次调用notify_one()或者notify_all()才会唤醒。如果是调用notify_all原创 2021-10-20 22:14:56 · 3036 阅读 · 0 评论 -
std::condition_variable::wait_for
使用示例,和wait的区别是wait_for可以设置一个超时时间#include <iostream>#include <atomic>#include <condition_variable>#include <thread>#include <chrono>using namespace std::chrono_literals; std::condition_variable cv;std::mutex cv_m;int原创 2021-10-20 21:31:55 · 2649 阅读 · 0 评论 -
C++ std::condition_variable::wait
std::condition_variable提供了两个等待函数:wait()和wait_for().条件变量是需要和一个互斥锁mutex配合使用,调用wait()之前应该先获得mutex,当线程调用 wait() 后将被阻塞,直到另外某个线程调用 notify_one或notify_all唤醒了当前线程。std::condition_variable::wait1.void wait( std::unique_lockstd::mutex& lock );2template< cl原创 2021-10-20 20:44:55 · 5084 阅读 · 3 评论 -
C++条件变量std::condition_variable
使用示例#include <iostream>#include <string>#include <thread>#include <mutex>#include <condition_variable> std::mutex m;std::condition_variable cv;std::string data;bool ready = false;bool processed = false; void worke原创 2021-10-20 20:09:35 · 170 阅读 · 0 评论 -
std::map emplace示例
emplaceemplace操作是从C++11开始引入新特性,emplace操作是直接通过参数构造元素而不是拷贝元素到容器中这样可以减少拷贝从而提高性能。对于map是没有emplace_front、emplace_after、emplace_back这些操作的。std::map<Key,T,Compare,Allocator>::emplace template<class...Args>std::pair<iterator,bool>empl...原创 2021-08-25 12:07:39 · 9200 阅读 · 0 评论 -
STD::map 插入insert详解
std::map<Key,T,Compare,Allocator>::insert std::pair<iterator,bool>insert(constvalue_type&value); (1) template<classP>std::pair<iterator,bool>insert(P&&value); (2) (since C++1...原创 2021-08-25 11:48:22 · 10403 阅读 · 0 评论 -
std::map初始化
1,静态初始化#include <iostream>#include <map>#include <string>#include <string_view> void print_map(std::string_view comment, const std::map<std::string, int>& m){ std::cout << comment; for (const auto&原创 2021-08-25 11:02:35 · 7888 阅读 · 0 评论 -
C/C++,linux,数据库学习网站博客推荐
C++/C1,cppreference中文版英文版这个是学习C++非常好的一个网站,对于C++基本所有的特性都有非常详细的说明,还有一个很厉害的地方就是上面有很多代码示例,而且这些示例都是能够在线编译,在线运行的。也可以把自己的代码放上去运行。2,微软文档微软文档微软文档C++微软官网有很多技术文档,微软对C++的共享是很大,他们的各种文档做得非常好。对于C++文档而言是比较全面规范,比较权威,还有很多示例,各种图表也不错。除了C++,还有C#,.NET等很多其它文档Li原创 2021-08-16 11:51:45 · 113 阅读 · 0 评论 -
C++ 智能指针 std::shared_ptr
c++中智能指针中的“智能”可以简单的理解为自动释放内存,这样就可以避免内存泄漏。具体怎么避免内存?它是怎样释放内存的呢?智能指针的实现是使用了RAII机制,即:资源获取即初始化。也就是说在对象构造的时候申请内存(资源),在对象生存周期结束的时候,在析构函数中释放内存。智能指针也是一个对象,是对c语言原生指针的封装,当智能指针的生存周期结束时,他会在析构函数中自动把他指向的对象给销毁。shared_ptr和unique_ptr的区别是它允许多个shared_ptr共享同一个对象。它的实现内部有一原创 2021-08-10 21:12:19 · 587 阅读 · 0 评论 -
一个C++原子变量初始化编译报错问题
代码如下:#include <atomic>std::atomic_int count = 0;int main(){ // Do something}这段代码编译之后会报如下错误:use of deleted function ‘std::__atomic_base<_IntTp>::__atomic_base(const std::__atomic_base<_IntTp>&) [with _ITp = int]’std::at原创 2021-07-27 19:34:47 · 5901 阅读 · 2 评论 -
GCC C++ auto_ptr源码分析
本文基于4.9.0版本gcc,本文代码路径:gcc-4.9.0\libstdc++-v3\include\backward\auto_ptr.h类结构auto_ptr的类图如下所示它只包含一个指针成员,提供了6个成员函数,如下表所示operator = 拷贝一个auto_ptr后释放源auto_ptr operator * 解引用对象 operator -> 解引用对象成员 release 释放auto_ptr get 获取指针...原创 2021-03-29 00:36:02 · 278 阅读 · 0 评论 -
C++ RAII特性及其应用:智能指针,lock_guard类
RAII英文全称是Resource Acquisition Is Initialization,资源请求即初始化,是 C++ 所特有的资源管理方式。它主要是用来解决资源泄漏问题。最常见的资源泄漏问题就是内存泄漏和死锁(忘记释放锁引起)。这里举一个互斥锁没有被正确释放的例子。std::mutex m;void bad() { m.lock(); // 请求互斥锁 f(); // 如果 f() 抛出原创 2021-03-28 15:47:08 · 776 阅读 · 0 评论 -
C++ STL insert和emplace性能对比
#include <chrono>#include <functional>#include <iomanip>#include <iostream>#include <set>#include <string> class Dew{ public: Dew(int _a, int _b, int _c) : a(_a), b(_b), c(_c) { ...原创 2021-03-24 00:14:51 · 1098 阅读 · 0 评论 -
C++ std::set_difference详解
算法set_difference可以用来求两个集合的差集,本文给出一个默认类型的示例和一个自定义类型的示例#include <algorithm>#include <iostream>#include <iterator>#include <string_view>#include <vector> auto print = [](const auto& v, std::string_view end = "") {..原创 2021-03-23 23:56:53 · 5493 阅读 · 0 评论 -
C++ STL set详解
template< class Key, class Compare = std::less<Key>, class Allocator = std::allocator<Key>> class set;std::set是一种关联型容器,是一个排序集合,可以用来存放Key类型的对象。set集合里的对象都是唯一的,所以通常可以用set来做去重。其中排序是通过Compare这个对比函数对象来完成的,因为要排序,对于自定义类型需要告诉编译器这个...原创 2021-03-23 00:26:42 · 2541 阅读 · 0 评论 -
C++ STL 堆算法: make_heap(), push_heap(), pop_heap(), sort_heap()
在c++20中引入了几个堆相关的算法:make_heap(), push_heap(), pop_heap(), sort_heap(), is_heap, is_heap_until(),现在来开始介绍这几个函数和写一个示例。make_heap 在一个迭代器范围内构造一个堆(默认最大堆) push_heap 往一个元素插入到堆的末尾的下一个位置 pop_heap 弹出堆顶元素,并把它放到末尾位置 sort_heap 把一个堆进行排序 is_heap .原创 2021-03-14 16:46:35 · 698 阅读 · 0 评论 -
C++ 原子操作CAS和lockless无锁队列
原子操作我们通常语义下是指不能被进一步分割的最小粒子,而在计算机中的原子操作一般是指“不可被中断的一个或一系列操作”,或者说是:多个线程执行一个操作,其中任何一个线程要么完全执行完这些操作,要么没有执行这个操作的任何一个步骤。在单核处理器系统中,能够在单条指令中完成的操作都可以认为是“原子操作”,因为在单条指令的执行过程中不会被中断。但是在多核时代,可能同时运行多个独立的CPU,即使是可以在单个指令中完成的操作也有可能会被干扰。举个例子,decl指令(递减指令),它可以分为三步:读,递减,写,这个.原创 2021-03-07 16:43:36 · 5035 阅读 · 0 评论 -
c++ singleton 单例类的实现
单例设计模式是一种软件设计原理,用于将类的实例化限制为最多一个对象。 当仅需要一个对象来协调整个系统中的运作时,单例模式就很有用。 例如,如果您使用的是将日志写入文件的记录器,则可以使用单例类创建此类记录器。class Singleton{public: ~Singleton(){}; Singleton(const Singleton&)=delete;//禁用拷贝构造函数 Singleton& operator=(const Singleton&原创 2021-03-06 12:35:34 · 481 阅读 · 0 评论 -
leetcode438. 找到字符串中所有字母异位词 C++解法
给定一个字符串s和一个非空字符串p,找到s中所有是p的字母异位词的子串,返回这些子串的起始索引。字符串只包含小写英文字母,并且字符串s和 p的长度都不超过 20100。说明:字母异位词指字母相同,但排列不同的字符串。不考虑答案输出的顺序。示例1:输入:s: "cbaebabacd" p: "abc"输出:[0, 6]解释:起始索引等于 0 的子串是 "cba", 它是 "abc" 的字母异位词。起始索引等于 6 的子串是 "bac", 它是 "abc...原创 2021-03-04 23:59:21 · 208 阅读 · 2 评论 -
c++遍历字符串的三种方式
#include <iostream> using namespace std;int main (){ string str = "abcdef"; for(unsigned int i = 0; i < str.length(); i++) { cout<<str[i]; //下标访问 } cout<<endl; for(auto c : str) { ...原创 2021-03-04 23:40:36 · 1759 阅读 · 1 评论 -
C++使用std::atomic_flag实现自旋锁
std::atomic_flag 构造函数std::atomic_flag 构造函数如下:atomic_flag() noexcept = default; atomic_flag (const atomic_flag&T) = delete;std::atomic_flag 只有默认构造函数,拷贝构造函数已被禁用,因此不能从其他的 std::atomic_flag 对象构造一个新的 std::atomic_flag 对象。如果在初始化时没有明确使用 ATOMIC_FLAG_I...原创 2021-02-25 22:44:54 · 1304 阅读 · 0 评论 -
STL deque
deque 是一种双端队列,是一种能动态调整大小的序列容器,可以在两端(前面或后面)扩展或收缩。不同的标准库实现不一样,但是通常是用动态数组来实现,一般都允许通过随机访问迭代器直接访问某个元素,并根据需要自动扩展和收缩容内存空间。这个特点和vector很像,但是vector不能自动收缩,而deque可以。deque的另一个特点是即使在容器的开头插入元素也能保证高效。但是,与vector不同,deque不能保证将其所有元素的存储空间都是连续的,这意味着通过指针+偏移的方式来访问元素可能比较危险,可能会越界。d原创 2021-02-08 18:14:20 · 137 阅读 · 4 评论 -
STL vector
vector是个顺序容器,可以认为是个变长数组。与数组一样,vector是使用连续的存储空间来保存元素,这意味着可以使用指向其元素的常规指针的偏移量来访问它们的元素,而且效率与数组一样高。vector的随机存取效率很高,能达到O(1)的时间复杂度,但也和数组一样,当从中间插入或者删除元素时,需要移动元素,效率比较低。但从其末尾添加或删除元素也相对高效。但与数组不同的是,vector的大小可以动态变化,容器在需要的时候会自动扩容。vector是使用动态分配的内存来保存元素,当插入一个新元素时如果内存已经不原创 2021-02-07 01:34:53 · 230 阅读 · 0 评论 -
自行实现C++11版本的 Optional和StringView
template <typename T>class Optional {public: Optional() = default; Optional(const Optional &) = default; Optional& operator=(const Optional &) = default; Optional(Optional &&) = default; Optional& oper.原创 2021-01-04 22:31:14 · 1264 阅读 · 0 评论