
C++
文章平均质量分 87
恋喵大鲤鱼
一条不止于编码的鱼。
展开
-
C qsort 与 C++ sort 函数
C++ 有两个常用的排序函数:sort 与 qsort。下面介绍二者用法与区别。原创 2024-03-19 22:23:06 · 952 阅读 · 0 评论 -
C++ std::condition_variable 条件变量用法
condition_variable(条件变量)是 C++11 中提供的一种多线程同步机制,它允许一个或多个线程等待另一个线程发出通知,以便能够有效地进行线程同步。condition_variable 需要与 mutex(互斥锁)一起使用。当线程需要等待某个条件变成真时,它会获取一个互斥锁,然后在条件变量上等待,等待期间会自动释放互斥锁。另一个线程在满足条件后会获取相同的互斥锁,并调用条件变量的 notify_one() 或 notify_all() 函数来唤醒等待的线程。原创 2023-09-22 20:29:21 · 804 阅读 · 0 评论 -
C++ memset 栈空间出现段错误
你是否曾遇到过在程序里面创建线程提示你资源不够,你是否曾遇到过在gcc 中加入 -g 选项,程序崩溃时却没有任何 core 文件产生。如果就,那你就要注意到ulimit命令了。本次错误也是由于系统对进程资源的限制导致了以上的奇怪的错误结果。memset 栈空间出现段错误是由于系统分每个进程分配的空间不足导致的。ulimit 通过一些参数选项来管理不同种类的系统资源。这里,我们将讲解这些参数的使用。ulimit 命令的格式为:ulimit [ options ] [limit]原创 2015-09-17 13:23:18 · 8061 阅读 · 1 评论 -
C++ malloc 与 new 的区别
C++ malloc 与 new 有什么区别?这是一道经典的面试题。原创 2022-09-08 21:15:43 · 637 阅读 · 0 评论 -
《C++ 进阶心法》书籍修正记录
书籍《C++ 进阶心法》初版由于时间和水平有限,出现部分有待完善甚至是错误的地方,特将修正点记录于此。C++ 临时对象(1)推理出输出结果:原来的Integer Constructorbefore returnInteger Copy ConstructorInteger Copy Constructor改为Integer ConstructorInteger Copy ...原创 2019-11-04 17:01:37 · 1152 阅读 · 7 评论 -
C++ 左值、右值与常引用
左值(Lvalue)是C++中的一个基本概念,指可寻址的非只读表达式。通俗来讲,凡是可以出现在赋值运算符左边的表达式都是左值。与左值相对的就是右值(Rvalue),只能出现在赋值运算右边的表达式都是右值,所以,左值一定可以作为右值,右值一定不能作为左值。理解左值的概念,需要注意一下几点:(1)左值一定是可以寻址的表达式,不能寻址的表达式不能作为左值。例如,表达式3+5是一个符号常量表达式,它不能被寻址,因此就不能作为左值。(2)常变量虽然可以寻址,但是由于只读的限制,也不能作为左值。原创 2015-08-27 16:11:30 · 5234 阅读 · 0 评论 -
C++ 链式操作
什么是链式操作?链式操作是利用运算符进行的连续运算(操作),它的特点是在一条语句中出现两个或者两个以上相同的操作符,如连续的赋值操作、连续的输入操作、连续的输出操作、连续的相加操作等都是链式操作的例子。原创 2015-07-18 16:52:45 · 6119 阅读 · 0 评论 -
C++ 函数重载、隐藏与覆盖的区别
C++ 规定在同一作用域中,同名函数的形式参数(指参数的个数、类型或者顺序)不同时,构成函数重载。函数隐藏指不同作用域中定义的同名函数构成函数隐藏(不要求函数返回值和函数参数类型相同)。比如派生类成员函数屏蔽与其同名的基类成员函数、类成员函数屏蔽全局外部函数。请注意,如果在派生类中存在与基类虚函数同返回值、同名且同形参的函数,则构成函数重写。重定义派生类中与基类同返回类型、同名和同参数的虚函数,构成虚函数覆盖,也叫虚函数重写。原创 2015-11-12 23:48:20 · 3260 阅读 · 1 评论 -
C++ 解引用操作符重载
“*”是一个一元操作符,它作用于指针,表示去除指针所指单元的内容。当某个类中对*操作符今次那个重载时,是将该类的对象当做一个指针看待,而用*操作符提取指针所指向的内容。考察如下程序。#include <iostream>using namespace std;template<typename T> class DataContainer{ T *p;public: DataCo原创 2015-11-22 00:54:24 · 8242 阅读 · 0 评论 -
C++ 获取类成员虚函数地址
1.GCC平台GCC平台获取C++成员虚函数地址可使用如下方法[1]^{[1]}:class Base{ int i;public: virtual void f1(){ cout<<"Base's f1()"<<endl; }};Base b;void (Base::*mfp)() = &Base::f1;printf(&quo原创 2017-02-21 16:54:13 · 2482 阅读 · 5 评论 -
C++ 接口继承与实现继承的区别和选择
1.接口继承与实现继承的区别《Effective C++》条款三十四:区分接口继承和实现继承中介绍的比较啰嗦,概括地说需要理解三点: (1)纯虚函数只提供接口继承,但可以被实现; (2)虚函数既提供接口继承,也提供了一份默认实现,即也提供实现继承; (3)普通函数既提供接口继承,也提供实现继承。 这里假定讨论的成员函数都是public的。这里回顾一下这三类函数,如下:class BaseCl原创 2017-02-13 16:34:44 · 4769 阅读 · 0 评论 -
C++ 临时变量的常量性
但如果把一个临时变量当作非const引用参数传进来,由于临时变量的特殊性,临时变量所在的表达式执行结束后,临时变量就会被释放,所以,一般说来, 修改一个临时变量是毫无意义的,据此,C++编译器加入了临时变量不能作为非const引用实参这个语义限制,意在限制这个非常规用法的潜在错误。很多人对此的解释是临时变量是常量,不允许赋值改动,所以作为非常量引用传递时,编译器就会报错。通过以上代码,可以看出在设计函数时,形参尽可能地使用 const,这样可以使代码更为健壮,将错误暴露于编译阶段。原创 2015-08-25 09:55:18 · 5542 阅读 · 5 评论 -
C++ 函数模板与分离编译模式
一个程序(项目)由若干个源文件共同实现,而每个源文件单独编译生成目标文件,最后将所有目标文件连接起来形成单一的可执行文件的过程成为分离编译模式。2.使用模板在连接时出错在C++程序设计中,在一个源文件中定义某个函数,然后在另一个源文件中使用该函数,这是一种非常普遍的做法。但是,如果定义和调用一个函数模板时也采用这种方式,会发生编译原创 2015-10-30 00:56:14 · 7044 阅读 · 3 评论 -
C++函数申明对函数模板实例化的屏蔽
C++函数匹配顺序C++语言引入模板机制后,函数调用的情形显的比C语言要复杂。当发生一次函数调用时,如果存在多个同名函数,则C++编译器将按照如下的顺序寻找对应的函数定义。原创 2015-10-29 14:06:54 · 2477 阅读 · 0 评论 -
C++ 模板实例化与调用
模板的实例化指函数模板(类模板)生成模板函数(模板类)的过程。对于函数模板而言,模板实例化之后,会生成一个真正的函数。而类模板经过实例化之后,只是完成了类的定义,模板类的成员函数需要到调用时才会被初始化。模板的实例化分为隐式实例化和显示实例化。......原创 2015-10-29 13:13:41 · 15125 阅读 · 0 评论 -
C++ cin 详解之终极无惑
cin 是 C++ 标准输入流对象,即 istream 类的对象。cin 主要用于从标准输入读取数据,这里的标准输入指终端键盘。此外,cout 是标准输出流对象,即 ostream 类的对象。cerr 是标准错误输出流对象,也是 ostream 类的对象。这里的标准输入指终端键盘,标准错误输出指终端屏幕。在理解 cin 功能时,不得不提标准输入缓冲区。原创 2015-09-25 17:24:15 · 200694 阅读 · 51 评论 -
C++ struct 与 union
C++是一种强类型语言。C++程序中的任何变量(或函数)必须遵循“先说明后使用”的原则。定义数据类型有两个方面的作用:一是决定该类型的数据在内存中如何存储,而是决定可对该类型的数据进行哪些合法的运算。...原创 2015-08-17 23:32:37 · 5275 阅读 · 0 评论 -
C++学习知识点
1. OOP面向对象程序设计的多态的理解答:多态:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。在运行时,可以通过指向基类的指针,来调用实现派生类中的方法。 C++中,实现多态有以下方法:虚函数,抽象类,重载,覆盖,模板。2.类的特征答:封装、继承和多态。3. C++与C#的区别(1)C++中类的申明时,不能给数据成员赋值,通常使用构造函数来完成。而C#可以。还有C++种成员函数原创 2016-01-06 17:35:24 · 1849 阅读 · 0 评论 -
C++ 构造函数抛出异常注意事项
从语法上来说,构造函数和析构函数都可以抛出异常。但从逻辑上和风险控制上,构造函数和析构函数中尽量不要抛出异常,万不得已,一定要注意防止资源泄露。1.构造函数中抛出异常在C++构造函数中,既需要分配内存,又需要抛出异常时要特别注意防止内存泄露的情况发生。因为在构造函数中抛出异常,在概念上将被视为该对象没有被成功构造,因此当前对象的析构函数就不会被调用。同时,由于构造函数本身也是一个函数,在函数体内抛出原创 2015-12-02 10:40:40 · 12188 阅读 · 5 评论 -
C++ struct 初始化与赋值
变量的赋值和初始化是不一样的,初始化是在变量定义的时候完成的,是属于变量定义的一部分,赋值是在变量定义完成之后想改变变量值的时候所采取的操作。的方式进行初始化,使用指定初始化,一个明显的优点是成员初始化顺序和个数可变,并且扩展性好,比如在结构体非末尾处增加字段时,避免了传统顺序初始化带来的大量修改。初始化与赋值有着本质的区别,初始化是变量定义时的第一次赋值,赋值则是定义之后的值的变更操作,概念上不同,所以实现上也不一样。结构体变量的赋值是不能采用大括号的方式进行赋值的,例如下面的赋值是不允许的。原创 2016-05-30 13:28:57 · 171766 阅读 · 11 评论 -
C++ 动态联编实现原理分析
代码编译运行环境:VS2012+Debug+Win32所谓动态联编,是指被调函数入口地址是在运行时、而不是在编译时决定的。C++语言利用动态联编来完成虚函数调用。C++标准并没有规定如何实现动态联编,但大多数的C++编译器都是通过虚指针(vptr)和虚函数表(vtable)来实现动态联编。 基本的思路是: (1)为每一个包含虚函数的类建立一个虚函数表,虚函数表的每一个表项存放的是个虚函数在内存中原创 2015-11-17 19:25:46 · 4670 阅读 · 4 评论 -
C++ 控制对象的创建方式和数量
通常情况下,对象创建在堆上还是在栈上,创建多少个,这都是没有限制的。但是有时会遇到一些特殊需求。1.禁止创建栈对象禁止创建栈对象,意味着只能在堆上创建对象。创建栈对象时会移动栈顶指针以“挪出”适当大小的空间,然后在这个空间上直接调用类的构造函数以形成一个栈对象。而当栈对象生命周期结束,如栈对象所在函数返回时,会调用其析构函数释放这个对象,然后再调整栈顶指针收回那块栈内存。在这个过程中是不需要oper原创 2017-02-12 18:38:54 · 1451 阅读 · 0 评论 -
C++ explicit 禁止单参构造函数隐式调用
在没有合适理由必须使用隐式转换的前提下,为了提高代码可读性以及避免单参数构造函数的隐式调用带来的潜在风险,建议使用explicit关键字阻止单参数构造函数的隐式调用。程序的本意是想打印输出int指针指向的内容,在没有合适的打印函数被调用时,应该由编译器在编译环节终止编译,报告错误。这种单参数构造函数被隐式调用在C++中是被默许的,但是这种写法很明显会影响代码的可读性,有时甚至会导致程序出现意外的错误。(2)不同类型对象的隐式转换。单参数构造函数隐式调用不仅仅会给代码可读性造成影响,有时会带来意外的结果。原创 2018-09-19 22:10:30 · 2820 阅读 · 1 评论 -
C++ 多态的两种形式
1.多态的概念与分类多态(Polymorphisn)是面向对象程序设计(OOP)的一个重要特征。多态字面意思为多种状态。在面向对象语言中,一个接口,多种实现即为多态。C++中的多态性具体体现在编译和运行两个阶段。编译时多态是静态多态,在编译时就可以确定接口使用的形式。运行时多态是动态多态,具体引用的接口在运行时才能确定。静态多态和动态多态的区别其实只是在什么时候将函数实现和函数调用关联起来,是...原创 2018-09-19 17:02:26 · 8758 阅读 · 0 评论 -
C++ typename 的双重含义
1.模板类型参数申明使用模板时,在申明模板类型参数时,我们经常有如下两种申明方式://方式一template &amp;amp;amp;amp;amp;amp;amp;lt;class T&amp;amp;amp;amp;amp;amp;amp;gt; CTest;//方式二template &amp;amp;amp;amp;amp;amp;amp;lt;typename T&amp;amp;amp;amp;amp;am原创 2018-09-18 00:56:45 · 2164 阅读 · 3 评论 -
C++ 模板元编程简介
1.概述模板元编程(Template Metaprogramming,TMP)是编写生成或操纵程序的程序,也是一种复杂且功能强大的编程范式(Programming Paradigm)。C++模板给C++提供了元编程的能力,但大部分用户对 C++ 模板的使用并不是很频繁,大致限于泛型编程,在一些系统级的代码,尤其是对通用性、性能要求极高的基础库(如 STL、Boost)几乎不可避免在大量地使用 C...原创 2018-09-17 20:24:39 · 3208 阅读 · 1 评论 -
C++ 认识容器的迭代器
的方法是和另外一个迭代器做比较,这个迭代器一般是集合的末尾,当我们的索引值等于末尾的索引值end时,认为迭代器已经达到了末尾。(1)拥有begin和end函数,它们均返回迭代器 ,其中end函数返回一个指向集合末尾,但是不包含末尾元素的值,即用集合范围来表示,一个迭代器的范围是 [ begin, end ) 一个左闭右开区间。但是,当删除多个元素时,程序会出现崩溃。原因是通过迭代器删除指定的元素时,指向那个元素的迭代器将失效,如果再次对失效的迭代器进行 ++ 操作,则会带来未定义行为,程序崩溃。原创 2018-08-01 21:43:10 · 914 阅读 · 2 评论 -
C++ 析构函数不要抛出异常
1.别让异常逃离析构函数的原因《Effective C++》第三版中条款08建议不要在析构函数中抛出异常,原因是C++异常机制不能同时处理两个或两个以上的异常。多个异常同时存在的情况下,程序若不结束,会导致不明确行为。如下代码:class Widget{public: ~Widget(){...} //假设这个可能吐出一个异常};void dosomething(){ v原创 2017-02-15 21:16:22 · 4431 阅读 · 0 评论 -
C++ 终结类
C++如何实现不能被继承的类,即终结类。Java中有final关键字修饰,C#中有sealed关键字修饰,C++11之前还没有类似的关键字来修饰类实现终结类,需编程人员手动实现。但从C++11开始,提出了final关键字来申明终结类。现在不通过C++11关键词final,来实现一个被能被继承的类。由于任何派生类的对象在创建的时候,都必需在派生类的构造函数中调用父类的构造函数。所以,只要类的构造...原创 2018-07-30 23:14:11 · 858 阅读 · 0 评论 -
C++ 发展概述
C++是一门以C为基础发展而来的一门面向对象的高级程序设计语言,从1983年由Bjarne Stroustrup教授在贝尔实验室创立开始至今,已有30多个年头。C++从最初的C with class,经历了从C++98、C++ 03、C++ 11、C++ 14再到C++17多次标准化改造,功能得到了极大的丰富,已经演变为一门集面向过程、面向对象、函数式、泛型和元编程等多种编程范式的复杂编程语言,入...原创 2018-06-19 14:41:53 · 1400 阅读 · 0 评论 -
C++ string 成员函数 length() size() 和 C strlen() 的区别
C++ string 成员函数length()等同于size(),但是和 C 库函数strlen()有着本质区别,使用时切勿混淆。原创 2018-03-13 22:15:29 · 96479 阅读 · 8 评论 -
C++ 临时对象
C++中临时对象又称无名对象。临时对象主要出现在如下场景。1.建立一个没有命名的非堆(non-heap)对象,也就是无名对象时,会产生临时对象。 2.构造函数作为隐式类型转换函数时,会创建临时对象,以值的方式传递,用作实参传递给函数。原创 2015-05-11 23:20:41 · 7756 阅读 · 4 评论 -
C++ 构造函数体内赋值与初始化列表的区别
C++构造函数初始化列表处提示出现 error: expected ‘{’ before ‘this'解决办法。原创 2015-08-24 18:51:48 · 2614 阅读 · 0 评论 -
C++ IO 格式控制
C语言中,我们可以通过函数printf和scanf进行格式化控制,而在C++中仍然包含了前者,但还提供了以下两种格式控制的方法: (1)使用流成员函数进行格式控制; (2)使用预定义操作符进行格式控制。下面来一一介绍。1.流成员函数控制IO格式流成员函数主要指ios类(流基类)中的成员函数,分别有: (1)设置状态标志流成员函数setf。 一般格式:long ios::setf(long f原创 2015-07-10 23:05:53 · 4778 阅读 · 1 评论 -
C/C++ 的全缓冲、行缓冲和无缓冲
1.简介基于流的操作最终会调用read或者write函数进行I/O操作。为了使程序的运行效率最高,流对象通常会提供缓冲区,以减少调用系统I/O库函数的次数。在Linux中,缓冲方式存在三种,分别是: (1)全缓冲。输入或输出缓冲区被填满,会进行实际I/O操作。其他情况,如强制刷新、进程结束也会进行实际I/O操作。对于读操作来说,当读入内容的字节数等于缓冲区大小或者文件已经到达结尾,或原创 2017-03-19 11:58:47 · 7788 阅读 · 1 评论 -
C/C++ sizeof(下)
sizeof作用于基本数据类型,在特定的平台和特定的编译中,结果是确定的,如果使用sizeof计算构造类型:结构体、联合体和类的大小时,情况稍微复杂一下。原创 2015-11-10 22:08:55 · 2540 阅读 · 1 评论 -
我所理解的 C++ 反射机制
在实际的项目中,听师兄说项目中用到了 C++ 反射,出于好奇,就查阅相关资料,发现强大的 C++ 本身并不支持反射,反而 Java 支持反射机制。当我得知这个事实时,唯 C++ 马首是瞻的我,心中暗自落泪,悲叹不已。但是,C++ 的拥趸们别难受,强大的 C++ 本身不支持,但却可以让我们手动实现,真的是曲径通幽处,禅房花木深。C++ 是不会辜负我们对它至死不渝的追逐。但是,说到 Java 的反射机制或者 C++ 用到了反射,如果没有真正的在项目中使用过,我们对它会感觉到陌生和不解。原创 2016-06-17 11:17:06 · 30693 阅读 · 29 评论 -
C++ 覆盖或删除指定位置的文件内容
我们经常使用ofstream或者fstream可写文件,使用ifstream可以写文件,但需要设置文件的打开状态为ios::out。C++中IO流打开模式使用位掩码来表示。IO流打开模式有: 成员常量 app append,追加模式,设置流指针在每一个操作前均指向文件流末尾 ate at end,设置流指针在打开时指向文件流末尾 binary 以二进制模式开打文件流......原创 2017-03-16 16:52:20 · 30078 阅读 · 6 评论 -
C++ 函数参数入栈方式与调用约定
要实现函数调用,除了要知道函数的入口地址外,还要向函数传递合适的参数。向被调函数传递参数,可以有不同的方式实现。这些方式被称为“调用规范”或“调用约定”。C/C++中常见的调用规范有__cdecl、__stdcall、__fastcall和__thiscall。原创 2015-08-10 17:16:11 · 6944 阅读 · 2 评论 -
浅论 C++ 的复杂性
C++ 拥有 30 多年的历史,作为一门影响广泛的编程语言,它所受到的关注和争论恐怕是任何一门其他的语言所不能比拟的。十几年前,Java 等新生语言的出现曾导致 C++ 信任危机,但最终 C++ 以自身非凡的品质屹立于主流编程语言的行列。在有着众多编程语言可以选择的今天,到底有没有必要学习、怎样学习、怎样使用 C++?对于广大程序员,特别是刚刚接触编程的初者,这些问题至关重要。C++ 遭受批评最多的是它的复杂性,对于这个话题,已经有很多文献讨论过。原创 2015-12-05 11:56:42 · 6307 阅读 · 0 评论