c++ 隐藏 重载 覆盖

这三个关键字在cpp上经常碰到且很容易混淆,所以在这里记录他们的区别 ##重载 (overload) 特征 在同一个类中 函数名相同 参数不同 与 virtual 关键字无关 例子 :::cpp class foo{ public: void printFoo(int x){cout<<x<<endl;} void printFoo(float x){cout<<x<<endl;} }; printFoo 名字相同但传入参数不同,这个情况就是重载了。 ##覆盖 (override) 特征 在子类和父类之间 函数名相同 参数相同 父类函数必须有 virtual 修饰 例子 :::cpp class father{ public: virtual void printHello(void){ cout<<"i am father"<<endl;} }; class son: public father{ public: virtual void printHello(void){ cout<<"i am son"<<endl;} }; 覆盖是实现多态的重要特性。 ##隐藏 特征 子类的函数名与父类相同,但参数不同,无论有没有 virtual 父类的方法都会被隐藏 子类的函数名与父类相同,参数相同,但是父类函数没有 virtual 关键字,父类的函数也会被隐藏。 函数如果被隐藏,其调用的方法不取决与实例,而取决于指向实例的指针。例如 有一个父亲的指针指向了其儿子的实例,当要调用这个指针的儿子方法的时候,其真正调用的是父方法,程序就达不到预期目的了。 例子 :::cpp class father { public: void printMethod(void); }; void father::printMethod(void){ cout<<"father"<<endl; } :::cpp class son: public father{ public: void printMethod(void); }; void son::printMethod(void){ cout<<"son"<<endl; } :::cpp int main(int argc, char *argv[]) { son tom; father *jason = &tom; tom....

October 24, 2013

HackerRank: Insertion Sort Part1

基础水题,插入排序第一部分 Input Format There will be two lines of input: s - the size of the array ar - the sorted array of integers Output Format On each line, output the entire array every time an item is shifted in it. Constraints 1<=s<=1000 -10000<=x<= 10000, x ∈ ar Sample Input 5 2 4 6 8 3 Sample Output 2 4 6 8 8 2 4 6 6 8 2 4 4 6 8 2 3 4 6 8 Explanation 3 is removed from the end of the array....

October 15, 2013

HackerRank: Insertion Sort Part2

第二部分要求我们使用插入排序来排列数组,并把结果打印出来。 Sample Input 6 1 4 3 5 6 2 Sample Output 1 4 3 5 6 2 1 3 4 5 6 2 1 3 4 5 6 2 1 3 4 5 6 2 1 2 3 4 5 6 例子中是从前往后遍历元素并排序。插入排序的效率并不高,时间复杂度 $$\theta(n^2)$$ :::c #include <stdio.h> #include <string.h> #include <math.h> #include <stdlib.h> #include <assert.h> void printAr(int ar_size, int* ar){ int i; for(i = 0; i < ar_size;i++){ printf("%d",ar[i]); printf(" "); } printf("\n"); } /* Head ends here */ void insertionSort(int ar_size, int * ar) { int i,j,value; for(i = 1; i < ar_size; i++){ j = i - 1; value = ar[i]; while(j >= 0 && ar[j] > value){ ar[j + 1] = ar[j]; j--; } if(j !...

October 15, 2013

Hacker Rank: Pairs

刚注册上 Hacker Rank ,出现了一条练手的题目,竟然不是著名的 Hello World ,而是这题 Pairs 。 连接 题目是这样的 Given N integers [N<=10^5], count the total pairs of integers that have a difference of K. [K>0 and K<1e9]. Each of the N integers will be greater than 0 and at least K away from 2^31-1 (Everything can be done with 32 bit integers). Input Format 1st line contains N & K (integers). 2nd line contains N numbers of the set....

October 11, 2013

向android frameworks 添加自定义系统服务

以添加控制LED的服务为例子简述 android 系统服务的编写。 ##分析 首先需要知道的是android 之所以能够提供系统服务,是因为进程间通信,系统服务一直在后台运行。当程序想使用这些服务的时候,只要申请使用就可以了。android使用自己的Binder实现了这种进程间通行。 我想实现一个控制LED的系统服务,但是不需要过度了解 Binder, 只需要在系统服务的框架中添加相应的代码就可以了。 ##实现 ###定义接口 aidl文件定义了服务端提供的接口 :::java //ILEDManager.aidl package android.app; interface ILEDManager { void setWifiLED(boolean flag); void setApLED(boolean flag); } 定义好好需要在编译文件添加文件。 :::java //Android.mk core/java/android/app/ILEDManager.aidl \ ###接口实现代码 定义了接口后,就需要实现服务端逻辑了。 :::java //LEDManagerService.java package com.android.server; import android.util.Slog; import android.os.IBinder; import android.os.Binder; import android.content.Context; import android.app.LEDManager; import android.app.ILEDManager; public class LEDManagerService extends ILEDManager.Stub{ private static final String TAG = "LEDManagerService"; private LightsService mLightsService; private Context mContext; private final LightsService.Light mWifiLight; private final LightsService....

September 25, 2013

向android系统添加ape音频格式(第二部分)

编译出了libapedec.so,后需要知道如何用这个库。 主要还是看MACLib.h这个头文件,因为我们要调的主要接口都在这个头文件中。其中有以下几个 :::c APE::IAPEDecompress * __stdcall CreateIAPEDecompress(const APE::str_utfn * pFilename, int * pErrorCode = NULL); 传入参数是文件名和错误代码的int指针,返回的是这个解码器的句柄IAPEDecompress。先获得APE的音频数据及相关信息,就要先调用此函数初始化解码器并获得其句柄。 :::c class IAPEDecompress { public: // destructor (needed so implementation's destructor will be called) virtual ~IAPEDecompress() {}; virtual int GetData(char * pBuffer, int nBlocks, int * pBlocksRetrieved) = 0; virtual int Seek(int nBlockOffset) = 0; virtual intn GetInfo(APE_DECOMPRESS_FIELDS Field, intn nParam1 = 0, intn nParam2 = 0) = 0; }; 获得了句柄后,就可以使用里面的函数获取我们需要的信息,例如GetInfo可以获得APE文件的相关信息,GetData可以获得解码后的数据,Seek可以跳转到APE数据的指定位置。 只要用好这些方法,就可以了,问题是如何在stagefright上面用。 ##StageFright android 4....

September 10, 2013

向android系统添加ape音频格式(第一部分)

要向Android系统添加一种音频格式,需要对stagefright有一定的了解,在android源码里的libstagefright文件夹里面,可以看到一大堆的Extractor,也就是各种格式的解码器了。我们就是要这里写一个APEExtractor。 撇开Android框架不说,我们还不知道要如何把APE格式的数据解为pcm,所以重中之重是先找到解析APE的方法。 ##Monkey’s audio 开源的力量很强大,APE的解码器不用自己苦逼的实现了,只要到http://www.monkeysaudio.com/下载源码,然后根据android平台修改下,编译成库,供框架调用就可以了。 说起来轻松,有些知识还是需要知道的。所以现在的目标就是把APE解码器编译成libmonkeysaudio.so ##Android.mk 要编译成库,最主要是写好Android.mk。下载下来的解码器的源码版本是4.12,也就是MAC_SDK_412.zip,解压后发现其代码没有Makefile,而且project只有vs2012和xcode两个版本。忍了。 Readme.txt 中有这么一句话 If you use C++, it’s recommended that you simply statically link to maclib.lib 所以熟悉其源码后发现用到的代码目录只有两个MACLib和Shared,其他可以扔垃圾桶了。 把这两个文件夹放到一个叫做libmonkeysaudio文件夹中,然后移到android源码中external目录,开始做代码修改。 首先是在MACLib 目录把md5.h改名为MD5.h,在Shared目录的All.h 里定义好环境为LINUX。 在libmonkeysaudio文件夹下编写Android.mk文件,内容如下 :::sh LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) LOCAL_MODULE:=libmonkeysaudio LOCAL_SRC_FILES := \ MACLib/APECompressCore.cpp \ MACLib/APECompress.cpp \ MACLib/APECompressCreate.cpp \ MACLib/APEDecompress.cpp \ MACLib/APEHeader.cpp \ MACLib/APEInfo.cpp \ MACLib/APELink.cpp \ MACLib/APESimple.cpp \ MACLib/APEtag.cpp \ MACLib/BitArray.cpp \ MACLib/MACLib.cpp \ MACLib/MACProgressHelper.cpp \ MACLib/md5.cpp \ MACLib/NewPredictor.cpp \ MACLib/NNFilter.cpp \ MACLib/Prepare.cpp \ MACLib/UnBitArrayBase....

September 1, 2013

DLNA/UPNP相关理论

之前炒得很热的多屏互动,其中就用到了upnp技术。 简单地说,upnp就是通过一些列网络协议,实现了网络内各种设备的通讯和数据传输。其中用到的网络协议有 基于HTTP的**SSDP(Simple Service Discovery Protocol)**作用是网络中的设备发现。 基于UDP的**GENA(General Event Notification Architecture)**事件通知框架,看到UDP就知道其是非可靠传输,一般用作控制设备或者回应时的消息协议。 基于TCP的**SOAP(Simple Object Access Protocol)**简单对象访问协议。 UPnP定义了通用的设备与控制点之间的交互协议,包括寻址、发现、描述、控制、事件、展示等部分,如下图: 寻址:设备通过DHCP或Auto-IP自动获取一个IP地址,并测试及定时检查地址可用性。 发现:通过SSDP协议,当设备加入网络时向控制点宣告其可用服务。同样,当控制点加入网络时允许其搜索到感兴趣的设备。 描述:使用XML形式,让控制点了解设备及其提供的功能。描述包括设备描述、服务描述、非标准厂商扩展等。 控制:采用SOAP协议(Web Service协议),控制点向服务发出动作,设备服务执行后返回结果或错误码。或者控制点查询服务的状态变量值。 事件:当服务状态变量发生改变时,发布者(服务)向订阅者发送事件消息,提醒订阅者状态变量改变。控制点采用GENA协议订阅服务所提供的事件。 展示:控制点采用浏览器获得设备展示页面。 ##Upnp影音架构 除了定义了上面的基本的通信行为,upnp还定义了一个AV架构。 UPnP定义的基本影音设备包括MediaServer(媒体服务器)、MediaRenderer(媒体渲染器)。其中MediaServer服务包括:AVTransport(AVT)、ConnectionManager(CM)、ContentDirectory(CDS)等,MediaRenderer服务包括:AVTransport(AVT)、ConnectionManager(CM)、RenderingControl(RCS)等。 基本上mediaserver是内容的提供者,controlpoint通过控制mediaserver,mediarenderer从mediaserver里取得数据并播放,那么mediarenderer就是内容的呈现者。 Control Point调用MediaServer的CDS::Browser/Search动作,获取MediaServer内容目录对象 Control Point调用MediaRenderer的CM::GetProtocolInfo动作,获取MediaRenderer支持的数据格式 Control Point对支持的格式进行内容选择 Control Point分别调用MediaServer及MediaRenderer的CM::PrepareForConnection建立连接 Control Point调用MediaRenderer的AVT::SetAVTransportURI动作,设置内容URI路径 Control Point调用MediaRenderer的AVT::Play动作,启动播放 MediaServer与MediaRenderer之间通过HTTP GET进行内容传输 Control Point调用MediaRenderer的RCS::SetVolumn动作,设置音量 内容传输完成,根据需要设置下一首音乐的URI Control Point分别调用MediaServer及MediaRenderer的CM::ConnectionComplete终止连接 ##DLNA 至于DLNA,就是在upnp的基础上,定了更多的标准,来实现家庭影音互动,其核心基础就是upnp。

August 29, 2013

快速排序

在比较算法中,快速排序可以算是明星算法了,因为他的常系数小,使得其总体性能比其他比较算法优秀。其性能基本上可以达到$\theta (n\lg n)$ ,但在某些极端情况其时间复杂度却是$\theta ({n}^{2})$。 快速排序的基本思想是遵循分而治之的思想的,其基本思路是: 分:在待排序的数据中选取一个数作为中心点,大于这个数的数统统放到右边,小于这个数的统统放在左边。这样就形成了左右两个子串。 治:两个子串重复1的动作 合并:无 ##分 所以最重要的是分这一步,这一步的伪代码如下 :::c Partition(A,p,q) // A[p,q] x<-A[p] i<-p for j<-p+1 to q do if A[j] <= x // <= 是小于等于的意思 then i<-i+1 exhange A[i]<->A[j] exchange A[p]<->A[i] return i 时间复杂度为$\theta(n)$ 下面给出一个例子,看如何分。 Ex. :::java 6 10 13 5 8 3 2 11 选取 pivot=6 i=0 j=1 :::java 6 10 13 5 8 3 2 11 pivot=6 i=0 j=3 i=i+1 -> i=1 exchange A[i]<->A[j] so: :::java 6 5 13 10 8 3 2 11 此时 i=1,j=3, 继续 :::java 6 5 13 10 8 3 2 11 i=1,j=5 i=2 exchange A[i]<->A[j] :::java 6 5 3 10 8 13 2 11 i=2,j=5 j继续自增 :::java 6 5 3 10 8 13 2 11 i=2,j=6 i=3 exchange A[i]<->A[j] :::java 6 5 3 2 8 13 10 11 i=3,j=6 直到结束,然后 exchange A[p]<->A[i] : A[0] <-> A[3] , 最后结果为 :::java 2 5 3 6 8 13 10 11 这样以6为轴,比6小的都在左边,比6大的都在右边,分结束。...

July 29, 2013

愣头青

标题的三个字,我一直打不出来,真是个没有自知之明的家伙。使用上十八般武艺,才得到 lèng tóu qīng 三个拼音和一个解释。 愣头青,是我们生活中常用的一个词,说的是某人做事情没有脑子,或不动脑子,从来不对事情的内容性质是非曲直等情况做分析判断就盲目采取行动,结果,因为用于行动的手段和事情发展的状况相矛盾,最后将不起眼的小问题变成了后果严重的大问题,好事变成了坏事。 这个形容对于我来说真的非常贴切。可悲的是,常常因为这个原因惹怒了女朋友大人。这次也是。 很多事情往往事后才反省,没有及时抓紧机会,最后换来一句:“you always miss chance”。直插要害,情绪几近失控。 在经历了一次失败挫折后,很快也要面临另一个chance,可是由于上一次的失败,我退缩了。因为害怕再次失败。而这次如果失败,后果与上一次不一样,可能会改变终生,我还不想落个终身遗憾。也正是这个思想,使我举棋不定。是做,还是迟一些再做? 失败后总要找些原因吧,是性格问题?是计划问题?被这样反问着。我觉得是态度问题。 今晚没什么心思看英语,打开了一个又一个的别人的博客看。看着看着,不禁陷入了沉思,不禁问起自己这三个清华保安的哲学问题:你是谁?你来自哪里?你将要去哪里? 是什么博客令我有这样的沉思? 一个是:最好金龟换酒,博客主据说是夫妻档,傅真,伦敦金融离职者,毛铭基,工程师。他们的博客告诉我什么是爱情,他们的书《藏地白皮书》,听说是个比童话更童话的日记。 另一个是西乔的两篇报道《西乔:我在过着很奢侈的生活》和《西乔的新出发:去往墙外》,在看这两文章之前我不知道谁是西乔,但是看过她画的漫画,她的思想我是很赞同的,也感到自己非常惭愧。 有意思的是夫妻档这两个博客主在结束gap year后将回国发展,西乔却要去加拿大,究竟他们以后的发展会怎样呢? 我自己呢?

July 26, 2013