Golang Assertion Go中所有的类型都可以被转化成interface{},通常在传入可变参数中的API中,可变参数的类型就是interface{}。func typeConversion(strs ...interface{}) (ret []string) { for _, s := range strs { ret = append(ret, string(s)) }}上述代码是不能运行的,错误为...
XRDP使用 很久没写博客了,最近公司测试使用到了远程桌面,花了一点时间研究了一下,记录一下心得。XRDP介绍Xrdp是一个开源工具,允许用户通过Windows RDP访问Linux远程桌面。 除了Windows RDP之外,xrdp工具还接受来自其他RDP客户端的连接,如FreeRDP,rdesktop和NeutrinoRDP。 Xrdp现在支持TLS安全层。linux服务器环境搭建我使用的是cent...
非递归快排 非递归快排通过使用栈来模拟函数栈的调用,每次将首尾指针存入到栈中,并对首尾之间区域进行快排。#include <iostream>#include <stack>#include <vector>using namespace std;//利用栈将序列的起始和末尾保存起来int partition(vector<int> &am...
C++虚函数和虚函数表原理 虚函数的地址存放于虚函数表之中。运行期多态就是通过虚函数和虚函数表实现的。类的对象内部会有指向类内部的虚表地址的指针。通过这个指针调用虚函数。虚函数的调用会被编译器转换为对虚函数表的访问:ptr-&gt;f(); //ptr代表this指针,f是虚函数*(ptr-&gt;vptr[1])(ptr);上述代码中,ptr代表一个this指针,ptr指向的vptr是类内部的虚表...
第八章 微调 四十一 针对可复制的形参,在移动成本低并且一定会被复制的前提下,考虑将其按值传递当构造函数需要对左值和右值进行分别处理的时候,我们有两种方法,一种是重载接受左值和右值的构造函数,另一种是写万能引用构造函数,这两种方法都有一定的局限性,左值右值重载构造函数会导致代码的冗余,而万能引用会匹配一些错误的类型。有一种新的方式,就是使用按值传递,函数内部将局部变量强转为右值进行移动构造。代码如下:...
第七章 并发API C++11将并发融入了语言和库中。三十五 优先选用基于任务而非基于线程的程序设计基于线程的设计就是使用std::thread来运行函数;基于任务的设计就是使用std::async来运行函数。int f();thread(f); //基于线程auto r = async(f); //基于任务使用async调用f的时候,传递给async的函数对象被看做是任务。在基于线程的调...
第六章 lambda表达式 lambda表达式是表达式的一种,它是源代码的组成部分。std::find_if(container.begin(), contianer.end(), [](int val){ return 0 &lt; val; });闭包是lambda表达式创建的运行期对象,根据不同的捕获模式,闭包会持有数据的副本或者引用。闭包类就是实例化闭包的类,每个lambda式都会出发编译器生成一个独一无...
第五章 右值引用、移动语义和完美转发 移动语义使得编译器可以将一些代价高昂的复制操作转移成移动操作。例如STL中的很多复制操作。移动构造函数和移动赋值运算符可以使用移动语义,创建只移对象成为可能,例如shared_ptr、unique_ptr和thread等等。完美转发使得人们可以撰写接受任何实参的模板函数,并将其转发到其他函数,目标函数会接受到与转发函数所接受的完全相同的实例。二十三 理解std::move和std::for...
dpdk无锁队列 这篇博客是从网上博客整理摘抄而来,具体参考的博客内容在文末给出。Linux无锁队列kfifo概述Linux内核中有一个先进先出的数据结构,采用环形队列的数据结构来实现,提供一个无边界的字节流服务。最重要的是,这个队列采用的是无锁的方式来实现。即当它用于只有一个入队线程和一个出队线程的场景时,两个线程可以并发操作,而不需要任何加锁行为,就可以保证kfifo的线程安全。 这个队列名为k...
dpdk存储系统 NUMA系统简介普通的南北桥系统里面主要是通过北桥进行数据的交换,这样系统的瓶颈在北桥中,NUMA(非一致性内存架构Non-Uniform Memory Architecture)系统可以解决这样的系统瓶颈。在这种架构下,在一个配有四核的机器中,不需要一个复杂的北桥就能将内存带宽增加到之前的四倍,这样有一个问题就是该系统中,访问内存花费的时间和处理器相关,之所以和处理器相关是因为该系统每个处理...
第四章 智能指针 智能指针裸指针问题如下:裸指针在声明中并未指出,裸指针指涉到的是单个对象还是一个数组。裸指针在声明中也没有提示是不是要对其进行虚构。换言之,无法得知指针是否拥有其指涉的对象。或者是否空悬指针的析构是不是拥有重载的delete操作符。要防止多于一次的释放和析构。C++存在的4种智能指针: std boost 功能说明 auto_ptr(C++98)...
dpdk线程亲和性 Linux对线程的亲和性是有支持的,在Linux内核中,所有线程都有一个相关的数据结构,称为task_count,这个结构中和亲和性有关的是cpus_allowed位掩码,这个位掩码由n位组成,n代码逻辑核心的个数。Linux内核API提供了一些方法,让用户可以修改位掩码或者查看当前的位掩码。sched_set_affinity(); //修改位掩码sched_get_affinit...
第三章 转向现代C++ 七 在创建对象时注意区分()和{}C++11中多了一种初始化的方式,就是通过{}来进行初始化,例如初始化一个int类型int x(0);int y = 0;int z{0};int z = {0};使用大括号初始化容器非常方便:vector&lt;int&gt; vec{1,2,3};大括号同样可以用来初始化类内非静态成员变量,当然也可以用=初始化,但不可以用()...
背包问题-背包九讲阅读笔记 背包问题0-1背包这是最简单的背包问题,简而言之就是每件物品只有一样,可以取或者不取,对于容量为V的背包,N件物品,每一件都可以尝试放入背包中,那么顺序就是遍历这N件物品,每遍历到一个新的物品,都尝试将当前物品放入背包中,看看是放入后得到的价值高还是不放的价值高,取最高者即可。所以需要一个二维数组w[N][V],这个二维数组中的每一个位置w[i][j]代表的意思是前i个物品在容量为...
C++11多线程实现的一道面试题 题目: 子线程循环 10 次,接着主线程循环 100 次,接着又回到子线程循环 10 次,接着再回到主线程又循环 100 次,如此循环50次,试写出代码。这里涉及到的问题是主线程和子线程之间的切换,也就是说子线程跑一下,然后阻塞,主线程再跑一下,然后在阻塞,如此各循环 50次,注意这里的“各循环”,因为主线程和子线程各自的循环是没有关系的,而是内部各自循环50次。 这里肯定要用...
第二章 auto 五 优先选用auto,而非显示型别声明C++11中的auto可以用来声明变量,其型别都是推导自其初始化产物,所以必须进行初始化,这样可以保证合法初始化。int x; //未进行初始化,编译没有问题,但后续可能有逻辑问题auto x; //未进行初始化,无法通过编译其次可以去掉提领迭代器来声明局部变量时写的超复杂代码://C++0xtemplate&amp;lt;typename T...
第一章 型别推导 第一章 型别推导一 理解模板型别推导函数模板类型如下:template &amp;lt;typename T&amp;gt;void f(ParamType param); //ParamType是一个T相关的类型f(expr); //推导T和ParamType的型别ParamType有三种类型:ParamType是个指针或引用,但不是万能引用ParamType是万能引...
Effective Mordern C++和现代C++的探索 导言现代C++学起来难度稍微大一点,需要更多的精力去查漏补缺,很高兴在2018年,我接触到了许多之前没想过的东西,也谢谢周围的人给我带来的动力。这篇读书笔记将涵盖现代C++(包括C++11和C++14)的部分内容,从《Effective Mordern C++》这本书读到和想到的内容。目录第1章 型别推导 第2章 auto 第3章 转向现代C++ 第4章 智能指针 第5章 ...
dpdk探究1-理解dpdk的运行逻辑 DPDK介绍DPDK主要功能:利用IA(intel architecture)多核处理器进行高性能数据包处理Linux下传统的网络设备驱动包处理的动作可以概括如下:数据包到达网卡设备网卡设备依据配置进行DMA操作网卡发送中断,唤醒处理器驱动软件填充读写缓冲区数据结构数据报文到达内核协议栈,进行高层处理如果最终应用在用户态,数据从内核搬移到用户态如果最终应用在内核态,在内核...
深度探索C++对象模型-第五章 构造、析构、拷贝语意学抽象基类仍然需要一个显式的构造函数以初始化成员变量。纯虚函数的存在纯虚函数可以被静态调用,不可以通过虚拟机制调用。但是纯虚析构函数一定要被定义。因为对于派生类来说,总要调用基类的析构函数,基类不定义析构函数会导致连接失败。一 “无继承”情况下的对象构造Plain OI’ Data类型:C风格结构体类型,无需构造和析构的过程,直接申请内存并复制内...
深度探索C++对象模型-第四章 Function语意学一 成员的各种调用方式1 非静态成员函数非静态成员函数采用隐式传入this指针的方式进行成员的调用。this指针指向对象中的成员。class A{public: A(const A &lhs){ a = lhs.a; b = lhs.b; c = lhs.c; }private:...
深度探索C++对象模型-第三章 Data语意学一 成员变量的绑定如果在类内部和外部出现了同名成员变量,而类的内部在成员变量声明前有内联成员函数的话,会有以下误解:extern float x;class A{public: int func(){ return X; }private: int x;};这里的x不会出现绑定错误的原因,因为C++内部将内联函数放到整个类的后面进行处理,...
深度探索C++对象模型-第二章 构造函数语意学一 默认ctor的构造操作在4种情况下,编译器会为未声明ctor的类合成一个默认的ctor。1 带有默认ctor的成员类对象如果一个类内含一个或一个以上的成员类对象,那么类的每一个ctor必须调用每一个成员类的默认ctor,编译器会扩张已经存在的ctor,在其中插入一些代码,使得用户写的代码被执行前,先调用必要的默认ctor。调用的顺序是这些类对象在类中声明的顺序...
深度探索C++对象模型-第一章 关于对象一 C++封装成本C++用类去定义对象时,系统会为每一个对象分配存储空间。每个对象所占用的存储空间只是该对象的数据部分(虚函数指针和虚基类指针也属于数据部分)所占用的存储空间,而不包括函数代码所占用的存储空间。 C++程序的内存格局通常分为四个区:全局数据区(data area),代码区(code area),栈区(stack area),堆区(heap area)(即...
Effetive C++读书笔记-第8、9章 8 定制new和delete & 9 杂项讨论49 了解new-handler的行为1 当operator new抛出异常以反映一个未获得满足的内存需求之前,它会先调用一个客户指定的错误处理函数,一个new-handler函数。为了指定new-handler函数,需要调用std::set_new_handler(),其参数是无法分配足够内存时该被调用的函数,返回值是即将被替...
Effetive C++读书笔记-第7章 7 模版与泛型编程41 了解隐式接口和编译期多态面向对象编程主要通过显式接口和运行期多态解决问题。显式接口:源代码中可见,在头文件中看到的类的接口。运行期多态:成员函数是virtual,传入类的引用或指针时,在运行时,会自动匹配接口,可能是基类的接口, 也可能是派生类的。模版和泛型编程主要通过隐式接口和编译期多态解决问题。隐式接口:typename T,函数中,会有类型...
Effetive C++读书笔记-第6章 6 继承和面向对象设计32 确定你的public继承塑膜出is-a关系public继承意味着“is-a”,适用于基类身上的每一件事情也一定适用于派生类,因为每一个派生类对象也是一个基类的对象。33 避免遮掩继承而来的名称1 派生类内的名称会遮掩基类内的名称,基类里面重载的所有同名称函数(包括纯虚函数,虚函数,普通成员函数)会被派生类中重写的函数所掩盖,在派生类中无法访问基类...
Effetive C++读书笔记-第5章 5 实现26 尽可能延后变量定义时的出现时间变量应在使用的时候进行构造,并且通过default构造函数构造出一个对象然后对它赋值,比直接在构造时指定初值效率差。27 尽量少做转型动作1 四种C++式转型const_cast:通常被用来将对象的常量性去除。dynamic_cast:主要用来执行安全向下转型(基类到派生类),也就是用来决定某对象是否归属于继承体系中的某个...
Effetive C++读书笔记-第4章 4 设计与声明18 让接口容易被正确使用,不易被误用理想上,如果用户企图使用一个接口而却没有获得预期的行为,代码就应该不通过编译,例如一个接口要求输入一个月份,此时输入小于1和大于12的数都是无效的,我们应该尽量使用不兼容这些数的接口,即输入小于1或者大于12的数就无法通过编译。可选的一个方法是使用enum,但是enum不具备类型安全性,也就是说可以被转换成其他的类型使用(如int)。...
C++ 智能指针 1 autp_ptr(C++11之前)功能简单,源代码简单,所以直接分析源代码(有部分格式改动)可以知道这是一个模版类(声明方法为auto_ptr<T>):首先是类需要用到的一些东西template<class _Ty> //前向声明class auto_ptr;template<class _Ty>struct auto_ptr_ref...
C++ 左值和右值 左值,右值在C++11中所有的值必属于左值、右值两者之一,右值又可以细分为纯右值、将亡值。在C++11中可以取地址的、有名字的就是左值,反之,不能取地址的、没有名字的就是右值(将亡值或纯右值)。举个例子,int a = b+c, a就是左值,其有变量名为a,通过&a可以获取该变量的地址;表达式b+c、函数int func()的返回值是右值,在其被赋值给某一变量前,我们不能通过变...
Effetive C++读书笔记-第3章 3资源管理系统常见的资源除了内存还包括文件描述符,互斥锁,数据库连接,网络socket等。13 以对象管理资源1 使用原始指针(如工厂函数返回构建的堆上资源的指针)容易因为忘记delete造成内存泄漏,解决的方法是获得资源后将其放入管理对象内,管理对象在超出其生存期后,会自动调用析构函数,只要在析构函数中执行内存的释放,就可以通过析构函数自动执行资源释放。这些管理对象被称为RAII...
Effetive C++读书笔记-第1、2章 1 熟悉C++ & 2 构造/析构/赋值运算2 尽量以const,enum,inline替换#define1 对于常量声明,尽量用const代替#define2 #define不具有封装性,所以在类内部用static const来代替。(声明时就要赋初值)3 也可以用枚举代替static const,因为枚举没有地址的概念,空间分配在常量区,所以无法对其取地址(C++中...
为什么const对象只能调用const成员函数,而不能调用非const成员函数? 在c++中,我们可以用const来定义一个const对象,const对象是不可以调用类中的非const成员函数,这是为什么呢?下面是我总结的一些原理。假设有一个类,名字为test代码如下:class test{ int i;public: void print(); test(int i);};我们知道c++在类的成员函数中还会隐式传入一个指向当前对象的this指针,所...
关于git和github的一些总结 git的相关命令通过git init命令把当前目录变成Git可以管理的仓库:git init添加文件到git仓库# 1用命令git add告诉Git,把文件添加到仓库:git add XXX# 用命令git commit告诉Git,把文件提交到仓库git commit -m "some words about change"为什么Git添加文件需要add,comm...
搬运的一些动态规划题目(C++实现) 1、连续子数组的最大和来源:剑指offer面试题31 题目,输入一个整形术组,数组里有整数也有负数,数组中一个或连续的多个整数组成一个子数组,求所有子数组的和的最大值,要求时间复杂度为O(n)例子:int arr[] = {1,-2,3,10,-4,7,2,-5}; 在遍历整个数组的过程中,我们可以发现数组中每一个数字为子数组尾部(假设长度为m),对应的子数组和,都是和前面m-...
C++ 引用声明为const const引用只读不可修改,与绑定对象是否为const无关。 非const引用可读可改,只可与非const对象对象绑定。const intival = 1024;//int &ref2 = ival; //error:nonconst reference to a const objectconst int&refval = ival; //ok:both refer...
STL 迭代器 迭代器偏特化的意义偏特化偏特化就是对部分模板参数指定特定的类型。 如一个萃取迭代器所指类型的类:template<typename T> //输入的T是迭代器类型,其内部实现了value_type类型struct iterator_traits{ typedef typename T::value_type value_type; //typenam...
STL 空间配置器 内存的申请和释放STL的内存分配和释放被详细区分为四个部分:内存配置由allocate()负责(内部实现为operator new),内存释放由deallocate()负责(内部实现为operator delete);对象构造由construct()负责(内部实现为placement new),对象析构操作由destroy()负责(内部实现为~T()【T为对应类型】)operator ne...
Linux 多进程多线程编程 一 创建进程1 进程号进程号的类型是pid_t(typedef unsigned int pid_t)。获得进程和父进程ID的API如下:#include <sys/types.h>#include <unistd.h>pid_t getpid();//获得进程IDpid_t getppid();//获得父进程ID2 进程复制进程复制可以...
C++ RTTI(运行阶段类型识别) 问题:假设有一个类层次结构,一个基类派生了很多类,则可以让基类的指针指向其中任何一个类的对象,那通过指针指向对象的时候,如何判断对象的类型呢? C++拥有RTTI(runtime type identification)这个特性 RTTI:运行阶段可以确定对象的类型。C++有3个支持RTTI的元素dynamic_cast操作符将使用一个指向基类的指针来生成一个指向派生类的指针,否则该操作...
C++ const 1用const 修饰函数的参数 如果参数作输出用,不论它是什么数据类型,也不论它采用“指针传递”还是“引用传递”,都不能加const修饰,否则该参数将失去输出功能。const 只能修饰输入参数: 如果输入参数采用“指针传递”,那么加const修饰可以防止意外地改动该指针,起到保护作用。 例如StringCopy 函数:void StringCopy(char*strDestinati...
C++ 四种类型转换 C++中存在四种类型转换操作符:static_cast、dynamic_cast、const_cast、reinterpret_cast。 下面对这四种类型转换操作符进行简要介绍:static_caststatic_cast提供编译时期的静态类型检测,可以完成以下几类类型转换: 1)完成基础数据类型 2)同一个继承体系中类型的转换 3)任意类型与空指针类型void*之间...
C++ 控制对象生成数量的一个方法 如果一个类希望自己的对象数量可以控制在一定范围的话,可以采用对象计数的方式。在类中添加对象当前的数量和对象总共的数量(都设置为静态的全局类型) 但是类可能会通过被继承或者其他方式产生新的对象,需要杜绝这种方式,所以采用伪构造函数的方式。 伪构造函数就是将构造函数定义为私有类型,然后通过其他的供油成员函数调用构造函数来实现对象的产生,从而杜绝了构造函数和复制构造函数这两种产生新的对象的途径(带有...
C++ 运算符重载和类型转换函数 C++中对于用户自定义类对象的运算,要进行重载操作。如class overload{public: ...private: int num;};overload o1, o2;int num;//要实现的加法操作如下:/*1*/overload o3 = o1 + o2;/*2*/overload o4 = o1 + (任意int型);/*3*/overl...
C++ mutable C++的类中,如果用mutable关键字修饰的成员变量,在任何成员函数中都可以被修改,甚至是const修饰的成员函数。#include <iostream>using namespace std;class Mute{public: Mute(int a, int b):NotmuteNum(a), muteNum(b){ } void muteTes...
C++中sizeof的一个特性 #include <iostream>using namespace std;int main(){ int a = 1; cout << sizeof(a = 3) << endl; cout << a << endl; return 0;}输出为4,1,而不是4,3 由输出可以知道,...
C++ new操作符 #include <iostream>#include <new>using namespace std;int main(){ //operator new申请一块内存空间,用来存储string对象 void *rawMemory = operator new(sizeof(string)); //用string指针指向此块内存空间,使这...
python输出格式化字符串 在Python中,采用的格式化方式和C语言是一致的,用%实现>>> 'Hello, %s' % 'world''Hello, world'>>> 'Hi, %s, you have $%d.' % ('Michael', 1000000)'Hi, Michael, you have $1000000.'%运算符就是用来格式化字符串的。在字符串内...
C++ 标准模板库中的排序 partial_sort()函数partial_sort接受一个middle迭代器,使序列中的middle-first个最小元素以递增顺序排序,置于[first, middle)内。template <class RandomAccessIterator> void partial_sort (RandomAccessIterator first, RandomAcce...
C++ trie实现拼写检查 trie:用键值的一部分来确定查找路径的树称为trie节点是一个对象,包含以下成员:一个叶/非叶节点标志,一个单词结束标志,一个指向字符串的指针,以及一个指向指针数组的指针,该指针指向同样类型的结构class TrieNonLeafNode{public: TrieNonLeafNode(){ } TrieNonLeafNode(char); //~TrieNonLeaf
浅析map和multimap应用的小程序 创建类如下:class Person{private: char *name; int age; friend class lesserAge;public: Person(const char *ch = NULL, int num = 0):age(num){ //1 name = new char[strlen(ch)+1];
C++ cout输出字符 cout输出字符时,可以使用单引号 :cout << ';' << endl; //输出分号";"仅可输出字符型,如果单引号内是两个或多个字符,则会输出对应的int值(将字符转换为对应ASCII码值) 如:cout << ';;' << endl; //输出15163“;”对应的ASCII码为59(0x3B),“;;”为0x3B3B,对应十进制为15163
C++ 二叉树实现词频分析 通过二叉树存单词,并且对总共的单词数量进行计数,二叉树自适应的将出现频率高的单词往上移动以减少二叉树的搜索时间。 代码如下/***********************genSplay.h***********************/#ifndef _GENSPLAY_H_#define _GENSPLAY_H_#include <iostream>using namespace std
C++ stringstream实现不同类型数据的转换 利用stringstream构造一个函数,可以将任意类型转换为string类型。//构造一个任意类型转换string类型的函数template<class T>void toString(string &s, const T &t){ stringstream ss; ss << t; s = ss.str(); //或ss >> s;}利用stringstr
C++ 递归实现简单语言解释器 程序可以解释赋值语句,完成的功能如下:判断它是够包含合法的赋值语句求所有表达式的值 输入输出模版如下: 递归包含直接递归和间接递归。例如:一个项可以是一个因子,或者一个因子后面跟着称号“*”(或“/”)以及另一个因子。而因子可能是一个标识符,一个数,圆括号中的表达式,或者带有负号的因子。 调用链为term()->factor()->expression()->term(); 代码如下
C++ Brute Force算法 BF算法,即暴风(Brute Force)算法,是普通的模式匹配算法,BF算法的思想就是将目标串S的第一个字符与模式串T的第一个字符进行匹配,若相等,则继续比较S的第二个字符和 T的第二个字符;若不相等,则比较S的第二个字符和T的第一个字符,依次比较下去,直到得出最后的匹配结果。BF算法是一种蛮力算法。 代码如下:#include <iostream>#include <string>usin
C++ 利用栈实现走迷宫 使用两个栈,一个用于初始化迷宫,一个用于回溯。#include <iostream>#include <string>#include <cstring>#include <stack>using namespace std;template<class T>class Stack:public stack<T>{public: T pop(){ T tmp =
C++ 字符串分割的一些记录 有一个string如下:string str = "1311|1337|1357|1294|1325|1337|1333|1340|1325|1347|1353|1350|1313|1341|1346|1336|";将这个string以符号 | 分割开,可以使用strtok函数。 str是要分割的字符串,s是分割的依据。strtok(char *str, char *s);第一次分割时str输入要
C++类模板 一、类模板定义及实例化1、类模板定义template<class 模板参数表>class 类名{// 类定义......};其中,template 是声明类模板的关键字,表示声明一个模板,模板参数可以是一个,也可以是多个,可以是类型参数 ,也可以是非类型参数。类型参数由关键字class或typename及其后面的标识符构成。非类型参数由一个普通参数构成,代表模板定义中的一个常量。template<
C++读写文件小程序 有一个txt文件,内容如下 观察文件开始为504B,说明这是一个压缩文件的十六进制编码,故我们需要通过读写文件来还原这个压缩文件。这里是一个简单的示例C++小程序。#include <iostream>#include <fstream>using namespace std;//int main()//{// char str[] = "fR4aHWwuFCYYVydFRxM
C++链表简单功能实现 实现的是一个小型图书馆的程序,功能包括增加新书,以及读者借书和还书等。 代码如下:#include <iostream>#include <string>#include <list>#include <algorithm>#include <cstring>using namespace std;class Patron;class Book{public: Book(){p
模板函数定义迭代器不识别的解决方法 模板函数如下:template typename T> //重载ostream &operatorconst list &lst){ list::const_iterator ref = lst.begin(); for( ; ref != lst.end(); ref++) out << *ref; return out;}编译时报错如下
C++ 友元函数 1.友元函数的简单介绍1.1为什么要使用友元函数在实现类之间数据共享时,减少系统开销,提高效率。如果类A中的函数要访问类B中的成员(例如:智能指针类的实现),那么类A中该函数要是类B的友元函数。具体来说:为了使其他类的成员函数直接访问该类的私有变量。即:允许外面的类或函数去访问类的私有变量和保护变量,从而使两个类共享同一函数。实际上具体大概有下面两种情况需要使用友元函数:(1)运算符重载的某些场合需
C++ 虚析构函数 1.对于一个空类型,sizeof求得的结果是1 这就是实例化的原因(空类同样可以被实例化),每个实例在内存中都有一个独一无二的地址,为了达到这个目的,编译器往往会给一个空类隐含的加一个字节,这样空类在实例化后在内存得到了独一无二的地址,所以空类所占的内存大小是1个字节。 一旦类中有其他的占用空间成员,则这1个字节就不在计算之内。 增加了构造函数和析构函数后: 由于构造函数和析构函数的调用与类
C-断言(assert) 1、assert宏的原型定义在#include <assert.h>void assert( int expression );assert的作用是现计算表达式 expression ,如果其值为假(即为0),那么它先向stderr打印一条出错信息,然后通过调用 abort 来终止程序运行。2、使用assert的缺点是,频繁的调用会极大的影响程序的性能,增加额外的开销。在调试结束后,可以通过在包含
注册与回调 何为回调(callback) 所谓回调,就是客户程序C调用服务程序S中的某个函数A,然后S又在某个时候反过来调用C中的某个函数B,对于C来说,这个B便叫做回调函数。例如Win32下的窗口过程函数就是一个典型的回调函数。 一般说来,C不会自己调用B,C提供B的目的就是让S来调用它,而且是C不得不提供。由于S并不知道C提供的B叫甚名谁,所以S会约定B的接口规范(函数原型),然后由C提前通过S的一个函
C++ Primer Plus : 3-处理数据 1. 超越整型限制的数据 C++不保证符号整型超越限制(上溢和下溢)时不出错//short范围:-32768~32767//unsigned short范围:0~65535#include using namespace std;int main(){ short i = 32767; unsigned short j = 0; cout "1:" //1
C++ Primer Plus : 2-开始学习C++ 1. 位于函数名前面的部分叫做函数返回类型,它描述的是函数返回给调用它的函数的信息。函数名后括号钟的部分叫做形参列表或参数列表,它描述的是从调用函数传递给被调用的函数的信息。2. 输出时,>操作符从输入流中抽取字符。3. 类是用户定义的一种数据类型。要定义类,需要描述它能够表示什么信息和可对数据执行哪些操作。类之于对象就像类型之于变量。
C和指针读书笔记(第十六章) 1. 整型函数 这组函数返回整型值。这个函数分为三类:算数,随机数和字符串转换。函数原型位于stdlib.h 1.1. 算数int abs(int value); //返回参数绝对值long int labs(long int value); //作用对象长整型div_t div(int numerator, int denominator); //第二个参数(分母)除以第一个参
C和指针读书笔记(第十五章) 1. perror()函数用于向用户报告错误,原型定义于stdio.hvoid perror(char const * message);如果message不是NULL并且指向一个非空的字符串,perror函数就打印这个字符串,后面跟一个分号和一个空格,然后打印出一条用于解释errno当前错误代码的信息。2. exit用于终止程序的执行,原型定义于stdio.hvoid exit(int statu
vim的使用方法记录 自动补全:youcompleteme ubuntu安装步骤sudo apt-get install vimsudo apt-get install vim-youcompletemesudo apt-get install vim-addon-managervam install youcompleteme:行号:跳转 :$:跳转到最后一行 /查找对象:查找 ctrl+*:查找当前光标
C语言中使用静态函数的好处 静态函数会被自动分配在一个一直使用的存储区,直到退出应用程序实例,避免了调用函数时压栈出栈,速度快很多。 关键字“static”,译成中文就是“静态的”,所以内部函数又称静态函数。但此处“static”的含义不是指存储方式,而是指对函数的作用域仅局限于本文件。 使用内部函数的好处是:不同的人编写不同的函数时,不用担心自己定义的函数,是否会与其它文件中的函数同名,因为同名也没有关系。 c语言中
关于Linux编程的一些记录 1. 编译libpcap的C文件时,gcc要加上 -lpcap2. 编译线程C文件 ,gcc要加上 -lpthread3. 多文件同时编译(a.c, a.h, b.c, b.h, main.c(包含a.h和b.h))gcc a.c b.c main.c -o main //如果有链接库就在后面加上要链接的库4. 打日志时候用, 在普通日志函数外套一层宏定义, 专...
C和指针读书笔记(第十四章) 1. #define的用法 #define指令把一个符号名与任意的一个字符序列联系在一起#define name stuff;//每当有符号name出现在这条指令之后,预处理器就会把它替换成stuff#define reg register;//为关键字register声明一个简短的别名#define do_forever for( ; ; );//声明一个更具描述性的符号来代替无限循
C和指针读书笔记(第十三章) 1. 指向指针的指针 赋值int i;int *pi;int **ppi;//把ppi初始化指向变量pippi = π//把pi(通过ppi间接访问)初始化为指向变量i*ppi = &i;2. int f; //一个整形变量int *f; //一个指向整型的指针int* f, g; //声明了一个指针f和一个普通的整形变量gint f();
C和指针读书笔记(第十二章) 1. 单链表P2351.1 单链表的结构typedef struct NODE{ STRUCT NODE *link; int value;}Node;//根指针只是一个指针//链表最后一个节点的指针字段的值为NULL1.2 单链表的插入
C和指针读书笔记(第九章) 1. 字符串以字符串常量的形式存储与字符数组中。字符串以NUL字节结尾,但NUL不是字符串的一部分,所以字符串的长度不包括NUL字节,局势它所包含的字符个数。头文件string.h包含了使用字符串函数的原型和声明。2. 计算字符串参数的长度#include<stdio.h>#include<string.h>#include<stddef.h>size_t strlen(char const *
C和指针读书笔记(第八章) 1. 数组名不用指针常量表示的两种情况:数组名作为sizeof的操作数:sizeof返回数组的长度,而不是指向数组的指针的长度。数组名作为操作符&的操作数:取一个数组名的地址所产生的是一个指向数组的指针,而不是指向某个指针常量值的指针2. 指针的效率: 首先声明(适用于接下来的所有函数):#define SIZE 50;int x[SIZE];int y[SIZE]
C和指针读书笔记(第七章) 1. 真函数是从表达式内部调用的,它必须返回一个值用于表达式的求值。这类函数的return语句必须包含一个表达式。通常表达式的类型就是函数声明的返回类型,只有当编译器可以通过寻常算术转换把表达式的类型转换为正确的类型时,才允许返回类型与函数声明的返回类型不同的表达式2. 传递给函数的标量参数是传值调用的。传递给函数的数组参数在行为上就像它们是通过传址调用的那样。3. 交换
C和指针读书笔记(第六章) 1. 通过一个指针访问它所指向的地址的过程称为间接访问或者解引用指针。这个用于执行间接访问的操作符是单目操作符 * 。2. NULL指针是一个特殊的指针变量,表示某个特定的指针不指向任何东西,要使一个指针变量为NULL,可以给它赋一个零值。 对指针进行解引用操作可以获得它所指向的值,但是NULL指针并未指向任何东西,所以对NULL指针进行解引用操作使非法的。在对指针进行解引用操作之前必须
C和指针读书笔记(第五章) 1. 算术操作符:+,-,*,/,% 除了取模运算,其余几个操作符既可以用于整型值也可用于浮点型值。2. 移位操作符:<<,>>3. 位操作符:AND(&),OR(|),XOR(^)【异或(相同为0,相异为1)】4. 复合赋值符:+=,-=,*=,/=,%=,<<=,>>=,&=,^=,!= 赋值运算符:=5. 单目运算符:!:逻辑反++和–:自增和自减-和+:用于产生操作数的负值和操作
C和指针读书笔记(第三章) 1. 整形:字符,短整型,整型,长整型,分为有符号和无符号两种。 长整型至少应该和整型一样长,整型至少应该和短整型一样长。2. 当一个字符串常量出现于一个表达式中,表达式所使用的值就是这些字符串存储的地址,而不是这些字符本身。因此可以把字符串常量赋值给一个“指向字符的指针”吗或者指向这些字符所存储的地址,但是不能把字符串常量赋值给一个字符数组,因为字符串常量的直接值是一个指针。3. 说明符可能是一
C和指针读书笔记(第一章) C和指针读书笔记1.“/* */”不能真正将代码从源文件删除,要从逻辑上删除一段C代码,更好的方法是使用#if#if 0 statements#endif2.标准I/O库: stdio.h 定义了EXIT_SUCCESS 和 EXIT_FAILURE的函数库:stdlib.h 操纵字符串:string.h 3.*C语言中,数组参数是以引用的方式进行传递的,而标量和常量则是